因此,高阶 集合/迭代器函数(例如pluck、filter、each、map和 friends )的酷之处在于它们可以混合和匹配以组成更复杂的操作集。
大多数语言都提供这些类型的函数(查找诸如集合、迭代器或枚举/可枚举之类的包)...有些提供的函数比其他的多,而且您通常会看到函数在不同语言中的命名方式不同(即 collect == map,减少==折叠)。如果您的语言中不存在某个函数,您可以从确实存在的函数中创建它。
至于你的测试用例......我们可以使用array_reduce来实现pluck。我发布的第一个版本依赖于array_map
;但是,我同意@salathe的观点,即array_reduce更简洁地完成这项任务;array_map是一个不错的选择,但你最终不得不做更多的工作。array_reduce
起初可能看起来有点奇怪,但如果回调组织得井井有条,一切都很好。
不那么天真的pluck
人还会检查它是否可以在迭代值上“调用”(函数/方法)。在下面的简单实现中,我们假设结构是散列(关联数组)。
这将设置测试用例数据(Fixtures):
<?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(/* no categoryId */ '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);
选择您喜欢的采摘版本
$preferredPluck = 'pluck_array_reduce'; // or pluck_array_map
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);
// is_scalar isn't perfect; to make this right for you, you may have to adjust
return array_filter($map, 'is_scalar');
}
旧版 PHP <5.3 的“采摘”
我们可以使用旧的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;
}
这里我们根据我们运行的 PHP 版本选择一个“pluck”版本来调用。如果您运行整个脚本,无论您使用什么版本,都应该得到正确的答案。
$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';
注意没有结尾'?>'。那是因为不需要它。离开它比保留它更能带来好处。
FWIW,看起来这是作为array_column添加到 PHP 5.5 的。