解释这个数组转置和展平函数是如何工作的
Explain how this array transposing and flattening function works
PHP 中的这个函数允许合并任意 N 个不同长度的数组,输出数组将按下一个顺序排列:Array1[0],Array2[0],..,ArrayN[0],Array1[1],Array2[1],..,ArrayN[1]...
:
function array_zip_merge() {
$output = array();
// The loop incrementer takes each array out of the loop as it gets emptied by array_shift().
for ($args = func_get_args(); count($args); $args = array_filter($args)) {
// &$arg allows array_shift() to change the original.
foreach ($args as &$arg) {
$output[] = array_shift($arg);
}
}
return $output;
}
// test
$a = range(1, 10);
$b = range('a', 'f');
$c = range('A', 'B');
echo implode('', array_zip_merge($a, $b, $c)); // prints 1aA2bB3c4d5e6f78910
虽然我了解此示例中的每个内置函数各自执行的操作,但我无法理解它们如何在此函数中协同工作,尽管包括解释性评论...
有人可以帮我分解一下吗?该功能按原样运行得很好,只是让我发疯,我不明白它是如何工作的...
P.S:这个函数取自Interleaving multiple arrays into a single array问题。
在 array_zip_merge 中,for 语句总是获取每个数组的第一个值并将它们添加到 output 变量分别。
因为 array_shift 删除了它 returns 的元素,在每个循环中第一个元素是不同的。当它因此变空时,循环无事可做并中断。
如果还是不明白,请询问您遇到问题的具体代码部分。
数组$a
、$b
和$c
分别有10个、6个和2个元素。
$a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
$b = ['a', 'b', 'c', 'd', 'e', 'f'];
$c = ['A', 'B'];
当您将数组作为参数提供给 array_zip_merge()
函数时,请查看 for
循环。 func_get_args()
将使用提供的所有参数设置 $args
。在第一个 for
循环开始时 运行,
$args = [$a, $b, $c];
count($args) = 3;
在 foreach
循环中,array_shift
将 return 每个数组的第一个元素,导致 $output
类似于
$output = [1, 'a', 'A'];
数组现在看起来像,
$a = [2, 3, 4, 5, 6, 7, 8, 9, 10];
$b = ['b', 'c', 'd', 'e', 'f'];
$c = ['B'];
在第一个 for
循环结束时,array_filter
函数将测试是否有任何数组为空并将其从 $args
中删除。同样的事情会发生在第二个 运行,并且在第二个 for
循环结束时,变量看起来像
$a = [3, 4, 5, 6, 7, 8, 9, 10];
$b = ['c', 'd', 'e', 'f'];
$c = [];
$output = $output = [1, 'a', 'A', 2, 'b', 'B'];
//because $c is empty array_filter() removes it from $args
$args = [$a, $b];
因此,在 for
循环的第三次迭代中,count($args)
将 return 2
。当 $b
的最后一个元素被 array_shift
删除后,count($args)
将 return 1
。迭代将继续,直到所有数组都为空
自定义函数实际上是一种转置和展平技术,可容纳 non-matrix 数据集。通过 non-matrix,我的意思是将三个数组推入一个数组,数据集中将出现柱状间隙。使用 implode(array_merge(...array_map(null, $a, $b, $c)))
will work by happenstance(因为您使用空字符串作为胶水对数据进行内爆,但在其他情况下,空元素的生成可能会扭曲结果。
我觉得借来的剧本很难理解。 for
循环会比 foreach()
简单得多。可以在函数定义中使用扩展运算符将传入的柱状数据声明为变量,而不是调用 func_get_args()
。
这是执行三步任务的一种方法(没有内爆):
- 转置 3 个数组的数据(隔离数据列)
- 从列数据中过滤空值
- 展平过滤后的二维数组(
array_merge(...$tranposedAndfiltered)
)
代码:(Demo)
var_export(
array_merge(
...array_map(
fn(...$col) => array_filter(
$col,
fn($v) => !is_null($v)
),
$a,
$b,
$c
)
)
);
如果不使用扩展运算符和空过滤执行转置更简单,只需在展平和内爆之前使用嵌套的 foreach 循环。 (Demo)
$output = [];
foreach ([$a, $b, $c] as $i => $array) {
foreach ($array as $k => $v) {
$output[$k][$i] = $v;
}
}
var_export(implode(array_merge(...$output)));
参见 Stack Overflow 的数组转置规范:Transposing multidimensional arrays in PHP
PHP 中的这个函数允许合并任意 N 个不同长度的数组,输出数组将按下一个顺序排列:Array1[0],Array2[0],..,ArrayN[0],Array1[1],Array2[1],..,ArrayN[1]...
:
function array_zip_merge() {
$output = array();
// The loop incrementer takes each array out of the loop as it gets emptied by array_shift().
for ($args = func_get_args(); count($args); $args = array_filter($args)) {
// &$arg allows array_shift() to change the original.
foreach ($args as &$arg) {
$output[] = array_shift($arg);
}
}
return $output;
}
// test
$a = range(1, 10);
$b = range('a', 'f');
$c = range('A', 'B');
echo implode('', array_zip_merge($a, $b, $c)); // prints 1aA2bB3c4d5e6f78910
虽然我了解此示例中的每个内置函数各自执行的操作,但我无法理解它们如何在此函数中协同工作,尽管包括解释性评论...
有人可以帮我分解一下吗?该功能按原样运行得很好,只是让我发疯,我不明白它是如何工作的...
P.S:这个函数取自Interleaving multiple arrays into a single array问题。
在 array_zip_merge 中,for 语句总是获取每个数组的第一个值并将它们添加到 output 变量分别。
因为 array_shift 删除了它 returns 的元素,在每个循环中第一个元素是不同的。当它因此变空时,循环无事可做并中断。
如果还是不明白,请询问您遇到问题的具体代码部分。
数组$a
、$b
和$c
分别有10个、6个和2个元素。
$a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
$b = ['a', 'b', 'c', 'd', 'e', 'f'];
$c = ['A', 'B'];
当您将数组作为参数提供给 array_zip_merge()
函数时,请查看 for
循环。 func_get_args()
将使用提供的所有参数设置 $args
。在第一个 for
循环开始时 运行,
$args = [$a, $b, $c];
count($args) = 3;
在 foreach
循环中,array_shift
将 return 每个数组的第一个元素,导致 $output
类似于
$output = [1, 'a', 'A'];
数组现在看起来像,
$a = [2, 3, 4, 5, 6, 7, 8, 9, 10];
$b = ['b', 'c', 'd', 'e', 'f'];
$c = ['B'];
在第一个 for
循环结束时,array_filter
函数将测试是否有任何数组为空并将其从 $args
中删除。同样的事情会发生在第二个 运行,并且在第二个 for
循环结束时,变量看起来像
$a = [3, 4, 5, 6, 7, 8, 9, 10];
$b = ['c', 'd', 'e', 'f'];
$c = [];
$output = $output = [1, 'a', 'A', 2, 'b', 'B'];
//because $c is empty array_filter() removes it from $args
$args = [$a, $b];
因此,在 for
循环的第三次迭代中,count($args)
将 return 2
。当 $b
的最后一个元素被 array_shift
删除后,count($args)
将 return 1
。迭代将继续,直到所有数组都为空
自定义函数实际上是一种转置和展平技术,可容纳 non-matrix 数据集。通过 non-matrix,我的意思是将三个数组推入一个数组,数据集中将出现柱状间隙。使用 implode(array_merge(...array_map(null, $a, $b, $c)))
will work by happenstance(因为您使用空字符串作为胶水对数据进行内爆,但在其他情况下,空元素的生成可能会扭曲结果。
我觉得借来的剧本很难理解。 for
循环会比 foreach()
简单得多。可以在函数定义中使用扩展运算符将传入的柱状数据声明为变量,而不是调用 func_get_args()
。
这是执行三步任务的一种方法(没有内爆):
- 转置 3 个数组的数据(隔离数据列)
- 从列数据中过滤空值
- 展平过滤后的二维数组(
array_merge(...$tranposedAndfiltered)
)
代码:(Demo)
var_export(
array_merge(
...array_map(
fn(...$col) => array_filter(
$col,
fn($v) => !is_null($v)
),
$a,
$b,
$c
)
)
);
如果不使用扩展运算符和空过滤执行转置更简单,只需在展平和内爆之前使用嵌套的 foreach 循环。 (Demo)
$output = [];
foreach ([$a, $b, $c] as $i => $array) {
foreach ($array as $k => $v) {
$output[$k][$i] = $v;
}
}
var_export(implode(array_merge(...$output)));
参见 Stack Overflow 的数组转置规范:Transposing multidimensional arrays in PHP