社区文档构建进行中,欢迎编辑。社区答疑群(非官方):717421103,点点小课堂(腾讯会议):5696651544

全站通知:

帮助:解析函数/arraydiff

来自WIKI实验室WIKI_BWIKI_哔哩哔哩
跳到导航 跳到搜索

arraydiff

计算差集。出自扩展 Arrays BWIKI和各大Wiki平台广泛使用此扩展。<br>在遥远的未来,它可能与Mediawiki新的并行解析器不兼容,请参阅扩展主页了解更多信息。


多个数组的差集,就是从第一个数组中去除所有存在于其他数组中的元素,得到的结果数组。参见:PHP array_diff 函数MediaWiki和Arrays扩展使用PHP语言开发,因此其底层行为取决于PHP的特性。

例如对集合 [math]\displaystyle{ A }[/math][math]\displaystyle{ B }[/math][math]\displaystyle{ C }[/math],它们的差集可以表示为 [math]\displaystyle{ A - B - C }[/math],即从[math]\displaystyle{ A }[/math] 中去除存在于 [math]\displaystyle{ B }[/math][math]\displaystyle{ C }[/math] 中的元素。

语法

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

示例

先定义数组:{{#arraydefine:a|2,1,1,3,blue,apple,apple}}{{#arraydefine:b|2,2,blue}}{{#arraydefine:c|3,blue}}
[math]\displaystyle{ A - B }[/math]{{#arraydiff:x | a | b }}1、1、3、apple、apple
[math]\displaystyle{ A - C }[/math]{{#arraydiff:x | a | c }}2、1、1、apple、apple
[math]\displaystyle{ A - B - C }[/math]{{#arraydiff:x | a | b | c }}1、1、apple、apple
[math]\displaystyle{ A - C - B }[/math]{{#arraydiff:x | a | c | b }}1、1、apple、apple

底层代码

/** 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 );
	}
代码包含了三个函数。其中函数 multiArrayOperation 会从给出的第一个数组(array_1)开始,逐一调用multi_arraydiff( array_1, array_i )。就是将首个数组逐一与其他数组求差集。
函数multi_arraydiff中调用了PHP array_diff 函数。两个元素只有在(string) $elem1 === (string) $elem2时视为一致。 即对PHP语言的字符串转换表达相同。
实际用例
一些Wiki使用了相关特性,如下所示这个静态列表可能在下列页面更改后过时仅供批判性参考