已经阅读了SO post,在PHP中,我知道您可以使用index
这样的迭代方式来获得array_map
:
array_map(function($item, $index) { ... }, $items, array_keys($items));
当我使用$index
时如何获得array_reduce
可用的密码?我尝试过:
array_reduce($items, array_keys($items), function($acc, $item, $index) { ... }, array());
array_reduce($items, function($acc, $item, $index) { ... }, array(), array_keys($items));
但是我似乎仍然无法在$index
中获得array_reduce
。以前有人成功做到过吗?
编辑
关于我为什么要问这个问题的一些背景。
我不想使用foreach
,因为我必须对foreach
之外的数组进行突变才能创建我的收藏集。我宁愿避免突变。
其他语言允许人们使用reduce
并访问JavaScript和Ruby中的当前索引。我希望在PHP中获得相同的功能。那好吧!看起来我将不得不使用foreach
创建数组,同时还要使当前索引处于迭代状态。
答案 0 :(得分:2)
您对array_reduce
中的获取索引的了解不存在。 Check documentation.
问题是为什么?
看,reduce用于降低到单个值的目的,它是聚合。您具有初始值,而下一个值则显示了减少策略。了解当前项目索引毫无意义。
在某些其他语言中,它们可能提供当前索引,但在PHP中不提供此索引array_reduce
。它是语言和功能设计的,在实现上有一些限制。
但这并不意味着您无法拥有它。您可以使用它,但不能通过回调!
$i = 0;
$data = [1, 2, 3, 4];
// (1)
$result = array_reduce($data, function ($c, $i) { return $c + $i; }, 0);
// (2)
array_reduce($data, function ($c, $i) { echo "$i\n"; $i++; return $c + $i; }, 0);
问题是,该函数旨在实现此目的。或者您正在尝试使用错误的功能。您可能正在寻找其他一些功能。
或者您也可以编写一个实现该功能的函数:)
答案 1 :(得分:1)
PHP中的数组是奇特的东西:它们可以用作列表,队列,字典,集合,有序字典以及各种其他多值结构。但是,大多数函数在编写时都考虑了其中一种或两种结构。
对于array_reduce
,该数组被视为 list -项目的有序集合。因此,数组的 keys 不会传递给回调。这对于常见情况来说很有意义,例如计算总数或平均值等。
毫无疑问,在某些情况下,您希望减少键-值对的有序字典;不幸的是,PHP没有为此提供功能。
另一方面,有两个相关的功能可能可以代替使用:
array_map
,它在每个元素上运行回调,并生成一个新数组,其中一个输入项对应一个输入项array_walk
,它在每个元素上运行回调并忽略结果,但可以通过引用获取第三个参数,从而可以累积副作用这三个函数也可以通过foreach
循环轻松实现,因此您可以编写自己的reduce
函数,例如( unested ):
function array_reduce_assoc(array $array, callable $callback, $initial=null) {
$carry = $initial;
foreach ( $array as $key => $value ) {
$carry = $callback($carry, $key, $value);
}
}
答案 2 :(得分:1)
You already know you how to get the index in array_map
, so you could use that to reduce instead if you like. Just use
a reference to the "carry" variable in the callback.
$example = ['a' => 1, 'b' => 2, 'c' => 3];
array_map(function($key, $value) use (&$reduced) {
$reduced .= "$key$value"; // for example
}, array_keys($example), $example);
echo $reduced; //a1b2c3
I'm not sure I see the advantage of this over foreach, but it's another possible way to do it.
答案 3 :(得分:0)
<?php
$data = ['one', 'two', 'three'];
$result = array_reduce($data, function($carry, $item){
$carry['out'] .= $carry['i'] . ') '. $item . '; ';
$carry['i']++;
return $carry;
}, ['out' => '', 'i' => 1] )['out'];
echo $result; // 1) one; 2) two; 3) three;
答案 4 :(得分:0)
我只是遇到了同样的问题。解决起来很简单。
$i = 0;
$p = array_reduce($array, function($output, $item) use (&$i) {
// use $i
// do something with $item and/or $output
$i++; // increment $i
return $output;
}, $initial);
&$i
通过$i
作为参考,并授予它更新的权利。
答案 5 :(得分:0)
这类似于another answer,但有几点不同。
首先,另一个答案提供了一个示例,但不是完整的示例。还有
其他答案将回调参数定义为$carry, $key, $value
。我觉得
$carry, $value, $key
会更好,因为它会匹配
JavaScript reduce。
它还会保留PHP自己的array_reduce的顺序,而只是添加 一个额外的争论。在我的示例中,我正在实现array_flip, 证明可能的事:
<?php
$a = ['May', 'June'];
$m = [];
$f = function ($m_acc, $s_cur, $n_idx) {
return $m_acc + [$s_cur => $n_idx];
};
foreach ($a as $n => $s) {
$m = $f($m, $s, $n);
}
print_r($m);