Tools 是非官方社区Wiki。社区文档正在编写中,欢迎参与。 Wiki编辑答疑群:717421103
版本250923.2
全站通知:

帮助:解析函数/arraydiff

来自WIKI实验室WIKI_BWIKI_哔哩哔哩
跳到导航 跳到搜索
arraydiff 悬浮框🟢稳定可用
计算数组的差集并存储为新数组
{{#arraydiff: 结果数组名 | 数组1 | 数组2 | ... | 数组N }}
扩展:Arrays
数组
变量
集合
相关函数
相关资源

arraydiff

计算数组的差集,从第一个数组中移除所有出现在其它数组中的元素,并将结果存入新数组。出自扩展 Arrays BWIKI和各大Wiki平台广泛使用此扩展。<br>在遥远的未来,它可能与Mediawiki新的并行解析器不兼容,请参阅扩展主页了解更多信息。

比如有数组 a=[1,2,3,4]b=[2,4],执行 {{#arraydiff:result|a|b}} 会得到 result=[1,3]

差集运算常用于数据过滤场景,如去除已处理元素、排除指定项等操作。

语法

{{#arraydiff: 结果数组名 | 数组1 | 数组2 | ... | 数组N }}

参数

结果数组名
用于存储结果的数组名称(区分大小写)
数组1
被减数组,作为差集运算的基准数组
数组2 ... 数组N
减数组,这些数组中的元素将从数组1中移除
支持多个减数组,按参数顺序依次执行差集运算

效果

  • 输出:不输出任何字符
  • 效果:创建或更新指定名称的结果数组,包含差集运算后的元素。运算逻辑为依次从第一个数组中移除所有出现在后续数组中的元素(数学表示:[math]\displaystyle{ A - B - C - \ldots }[/math])。结果数组的索引会被重新组织为从 0 开始的连续数字索引。

示例

先定义三个数组:

  • a = 2、1、1、3、blue、apple、apple
  • b = 2、2、blue
  • c = 3、blue
差集运算 调用代码 输出结果
[math]\displaystyle{ A - B }[/math]

移除 b 中的元素

{{#arraydiff:x | a | b }}{{#arrayprint:x}} 1、1、3、apple、apple
[math]\displaystyle{ A - C }[/math]

移除 c 中的元素

{{#arraydiff:y | a | c }}{{#arrayprint:y}} 2、1、1、apple、apple
[math]\displaystyle{ A - B - C }[/math]

移除 b 和 c 中的元素

{{#arraydiff:z | a | b | c }}{{#arrayprint:z}} 1、1、apple、apple
[math]\displaystyle{ A - C - B }[/math]

移除 c 和 b 中的元素

{{#arraydiff:w | a | c | b }}{{#arrayprint:w}} 1、1、apple、apple

使用场景

适用于需要从数据集中排除特定元素的场景:

过滤指定项:从完整列表中移除特定的元素。

条件筛选:根据多个排除条件过滤数据,如"显示所有文章,但排除草稿、存档和已删除的"。

集合对比:对比两个数据集的差异,找出"仅在 A 中存在而不在 B 中"的元素。

相比手动编写条件判断,使用 arraydiff 的优势:

  • 简洁高效:一次调用完成多重过滤
  • 逻辑清晰:数学集合语义,易于理解维护
  • 动态处理:可处理 SMW 查询等动态数据源
  • 可组合:配合其他 Arrays 函数实现复杂数据处理流程

底层代码

/** mediawiki-extensions-Arrays-REL1_37 ExtArrays.php
* Usage:
*    {{#arraydiff:arrayid_new |array1 |array2 |... |array n}}
*
*    Set operation, {white} = {red, white} - {red}
*    See: http://www.php.net/manual/en/function.array-diff.php
*/
public static function pfObj_arraydiff( &$parser, $frame, $args ) {
	self::get( $parser )->multiArrayOperation( $frame, $args, __FUNCTION__, false );
	return '';
}

private function multi_arraydiff( $array1, $array2 ) {
	// keys will be preserved!
	return array_diff( $array1, $array2 );
}

/**
	 * Base function for operations with multiple arrays given thru n parameters
	 * $operationFunc expects a function name prefix (suffix 'multi_') with two parameters
	 * $array1 and $array2 which will perform an action between $array1 and $array2 which
	 * will result into a new $array1. There can be 1 to n $hash2 in the whole process.
	 *
	 * Note: This function is similar to that of Extension:HashTables.
	 *
	 * @since 2.0
	 *
	 * @param PPFrame $frame
	 * @param array $args
	 * @param string $operationFunc name of the function calling this. There must be a counterpart
	 *        function with prefix 'multi_' which should have two parameters. Both parameters
	 *        will receive an array, the function must return the result array of the processing.
	 * @param bool $runFuncOnSingleArray whether the operationFunc function should be run in case
	 *        only one array id is given. If not, the original array will end up in the new array.
	 */
	protected function multiArrayOperation( PPFrame $frame, array $args, $operationFunc, $runFuncOnSingleArray = true ) {
		$args = array_values( $args );
		$numArgs = count( $args );

		$lastArray = null;
		$operationRan = false;
		$finalArrayId = trim( $frame->expand( $args[0] ) );
		$operationFunc = 'multi_' . preg_replace( '/^pfObj_/', '', $operationFunc );

		// For all arrays given in parameters 2 to n (ignore 1 because this is the name of the new array)
		for ( $i = 1; $i < $numArgs; $i++ ) {
			$argArrayId = trim( $frame->expand( $args[ $i ] ) );

			// ignore all tables which do not exist
			if ( $this->arrayExists( $argArrayId ) ) {
				$argArray = $this->getArray( $argArrayId );
				if ( $lastArray === null ) {
					// first valid array, process together with second...
					$lastArray = $argArray;
				} else {
					// second or later hash table, process with previous:
					$lastArray = $this->{ $operationFunc }( $lastArray, $argArray ); // perform action between last and current array
					$operationRan = true;
				}
			}
		}

		// in case no array was given at all:
		if ( $lastArray === null ) {
			$lastArray = [];
		}

		global $egArraysCompatibilityMode;

		if ( !$operationRan && $egArraysCompatibilityMode
			&& $operationFunc !== 'multi_arraymerge' // only exception was 'arraymerge'
		) {
			/*
			 * COMPATIBILITY-MODE:
			 * Before version 2.0 we didn't create a new array in case only one array was given.
			 * The only exception was 'arraymerge' which did duplicate the array.
			 */
			return;
		}

		// if the operation didn't run because there was only one or no array:
		if ( !$operationRan && $runFuncOnSingleArray ) {
			$lastArray = $this->{ $operationFunc }( $lastArray );
		}

		// re-organize all keys since some 'multi_' functions will preserve keys!
		$lastArray = array_merge( $lastArray );

		$this->setArray( $finalArrayId, $lastArray );
	}

处理流程

  1. 参数验证:提取所有数组名,忽略不存在的数组。若所有数组均不存在,创建空结果数组
  2. 差集运算:从第一个有效数组开始,依次与后续数组求差集。其中元素比较基于字符串
  3. 结果存储:将最终差集结果存入指定的结果数组名

实际用例

一些Wiki使用了相关特性,如下所示这个静态列表可能在下列页面更改后过时仅供批判性参考