所以,
高阶 集合/迭代器函数(例如
pluck、
filter、
each、
map等)的酷炫之处在于它们可以混合搭配,组成更复杂的操作集合。
大多数语言都提供这些类型的函数(查找类似于collection、iterator或enumeration/enumerable的包),有些语言提供的函数比其他语言更多,并且你通常会看到这些函数在不同语言中的命名不同(例如collect == map,reduce == fold)。如果你的语言中
不存在该函数,你可以从已有的函数中创建它。
关于您的测试用例...我们可以使用
array_reduce来实现
pluck。我最初发布的第一个版本依赖于
array_map
;然而,我同意
@salathe的观点,
array_reduce对于这个任务来说更加简洁;
array_map是一个可以接受的选择,但最终你需要做更多的工作。一开始
array_reduce
可能看起来有些奇怪,但如果回调函数组织得好,一切都会很顺利。
一个不那么幼稚的
pluck
也会检查它是否可以在迭代的值上“调用”(一个函数/方法)。在下面的幼稚实现中,我们假设结构是哈希表(关联数组)。
这将设置测试用例数据(固定装置):
<?php
$data[] = array('categoryId' => 1, 'eventId' => 2, 'eventName' => 3, 'vendorName' => 4);
$data[] = array('categoryId' => 5, 'eventId' => 6, 'eventName' => 7, 'vendorName' => 8);
$data[] = array('categoryId' => 9, 'eventId' => 10, 'eventName' => 11, 'vendorName' => 12);
$data[] = array( 'eventId' => 10, 'eventName' => 11, 'vendorName' => 12);
$data[] = array('categoryId' => false,'eventId' => 10, 'eventName' => 11, 'vendorName' => 12);
$data[] = array('categoryId' => 0.0, 'eventId' => 10, 'eventName' => 11, 'vendorName' => 12);
选择您喜欢的pluck版本
$preferredPluck = 'pluck_array_reduce'
PHP 5.3+ 中的 "pluck":array_reduce 提供了一种简洁的实现方法,但不像 array_map 版本那样易于理解:
function pluck_array_reduce($key, $data) {
return array_reduce($data, function($result, $array) use($key){
isset($array[$key]) &&
$result[] = $array[$key];
return $result;
}, array());
}
"
PHP 5.3+中的“pluck”:array_map对此并不完美,因此我们需要进行更多的检查(它仍然不能处理许多潜在情况):
"
function pluck_array_map($key, $data) {
$map = array_map(function($array) use($key){
return isset($array[$key]) ? $array[$key] : null;
}, $data);
return array_filter($map, 'is_scalar');
}
对于PHP5.3以下版本的“pluck”
我们本可以使用旧版create_function; 但这是不好的形式,不被推荐,也不够优雅,因此我决定不展示它。
function pluck_compat($key, $data) {
$map = array();
foreach ($data as $array) {
if (array_key_exists($key, $array)) {
$map[] = $array[$key];
}
}
unset($array);
return $map;
}
在这里,我们选择调用“pluck”的版本,根据我们正在运行的PHP版本。如果您运行整个脚本,则无论您使用哪个版本,都应该得到正确的答案。
$actual = version_compare(PHP_VERSION, '5.3.0', '>=')
? $preferredPluck('categoryId', $data)
: pluck_compat('categoryId', $data);
$expected = array(1, 5, 9, false, 0.0);
$variance = count(array_diff($expected, $actual));
var_dump($expected, $actual);
echo PHP_EOL;
echo 'variance: ', $variance, PHP_EOL;
print @assert($variance)
? 'Assertion Failed'
: 'Assertion Passed';
注意,结尾处没有'?>'。这是因为它不需要。去掉它比保留它更有好处。
顺便说一句,看起来这将作为
array_column添加到PHP 5.5中。
array_reduce()
是错误的函数。它旨在“将数组减少为单个值”。在其他语言中也是如此。您应该使用array_map()
或array_walk()
进行重写...这也将简化代码。 - doublejosharray_reduce
在这里很好用。它将一个数组中的数组缩减为一个值的数组。 - Michael