在 PHP 中,是否有一个函数返回一个由关联数组数组中的键值组成的数组?
我确定这个问题以前有人问过,我很抱歉没有先找到它.
I'm sure this question has been asked before, my apologies for not finding it first.
原始数组:
[0] => Array
(
[categoryId] => 1
[eventId] => 2
[eventName] => 3
[vendorName] => 4
)
[1] => Array
(
[categoryId] => 5
[eventId] => 6
[eventName] => 7
[vendorName] => 8
)
[2] => Array
(
[categoryId] => 9
[eventId] => 10
[eventName] => 11
[vendorName] => 12
)
我希望得到的结果是:print_r(get_values_from_a_key_in_arrays('categoryId', $array));
My hoped for result out of: print_r(get_values_from_a_key_in_arrays('categoryId', $array));
[0] => 1
[1] => 5
[2] => 9
我只是在寻找比编写自己的基于 foreach 的函数更简洁的东西.如果 foreach 是答案,我已经准备好了.
I'm just looking for something cleaner than writing my own foreach based function. If foreach is the answer, I already have that in place.
我不想使用硬编码的密钥,我只是展示了对解决方案的示例调用.谢谢!^_^
I don't want to use a hard-coded key, I was just showing an example call to the solution. Thanks! ^_^
PHP 5.3 的快速获取解决方案:
private function pluck($key, $data) {
return array_reduce($data, function($result, $array) use($key) {
isset($array[$key]) && $result[] = $array[$key];
return $result;
}, array());
}
所以,higher 很酷的事情-order 集合/迭代器函数,例如pluck, 过滤器,每个,map,和朋友们一起,他们可以混合搭配来组成更复杂的操作集.
So, the cool thing about higher-order collection/iterator functions such as pluck, filter, each, map, and friends is that they can be mixed and matched to compose a more complex set of operations.
大多数语言都提供这些类型的函数(寻找诸如集合、迭代器或枚举/枚举之类的包)……有些提供的函数比其他的多,您通常会看到这些函数在不同语言中的命名方式不同(即 collect == 地图,减少 == 折叠).如果函数在您的语言中不存在,您可以从存在的函数中创建它.
Most languages provide these types of functions (look for packages like collection, iterator, or enumeration/enumerable)...some provide more functions than others and you will commonly see that the functions are named differently across languages (i.e. collect == map, reduce == fold). If a function doesn't exist in your language, you can create it from the ones that do exist.
至于您的测试用例...我们可以使用 array_reduce 来实现 pluck.我发布的第一个版本依赖于array_map
;但是,我同意 @salathe array_reduce 对这个任务更简洁;array_map 是一个不错的选择,但你最终不得不做更多的工作.array_reduce
乍一看可能有点奇怪,但如果回调井井有条,一切都会好起来的.
As for your test case...we can use array_reduce to implement pluck. The first version I posted relied on array_map
; however, I agree with @salathe that array_reduce is more succinct for this task; array_map is an OK option, but you end up having to do more work in the end. array_reduce
can look a bit odd at first, but if the callback is neatly organized, all is well.
一个不那么天真的 pluck
还会检查它是否可以在迭代值上调用"(一个函数/方法).在下面的简单实现中,我们假设结构是一个散列(关联数组).
A less naive pluck
would also check to see if it can "call" (a function/method) on the iterated value. In the naive implementation below, we assume the structure to be a hash (associative array).
这将设置测试用例数据(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);
选择您喜欢的 pluck 版本
$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;然而,它的形式很糟糕,不推荐,也不优雅,因此,我决定不展示它.
We could have used the legacy create_function; however, it is bad form, not recommended, and also not at all elegant, thus, I've decided not to show it.
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';
注意没有结尾?>".那是因为它不需要.离开它比保留它更好.
Notice there is no ending '?>'. That is because it isn't needed. More good can come of leaving it off than from keeping it around.
FWIW,看起来这是作为 array_column.
FWIW, it looks like this is being added to PHP 5.5 as array_column.