在 PHP 中,是否有一个函数从关联数组数组中返回由键值组成的数组?

我相信这个问题以前问过,我很抱歉没有先找到它。

原始数组:

[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));

[0] => 1
[1] => 5
[2] => 9

我只是在寻找比编写自己的基于foreach的函数更干净的东西。如果前言是答案,我已经有了答案。

编辑:我不想使用硬编码键,我只是展示了对解决方案的示例调用。谢谢!^_^

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());
}

答案 1

因此,高阶集合/迭代器函数(如拨取过滤器每个映射和友元)的酷炫之处在于,它们可以混合和匹配,以组成一组更复杂的操作。

大多数语言都提供这些类型的函数(查找集合,迭代器或枚举/枚举等包)...有些函数比其他函数更多,您通常会看到这些函数在不同语言中的命名方式不同(即 collect == map,reduce == fold)。如果您的语言中不存在某个函数,则可以从存在的函数创建它。

至于你的测试用例...我们可以使用array_reduce来实现拔毛。我发布的第一个版本依赖于;但是,我同意@salathe即array_reduce更适合这项任务;array_map是一个不错的选择,但最终你不得不做更多的工作。 乍一看可能看起来有点奇怪,但如果回调组织得整整齐齐,一切都很好。array_maparray_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(/* 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+的“拔”: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+的“拔毛”: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中。


答案 2

映射是您需要的:

$input = array(
    array(
        'categoryId' => 1,
        'eventId' => 2,
        'eventName' => 3,
        'vendorName' => 4,
    ),
    array(
        'categoryId' => 5,
        'eventId' => 6,
        'eventName' => 7,
        'vendorName' => 8,
    ),
    array(
        'categoryId' => 9,
        'eventId' => 10,
        'eventName' => 11,
        'vendorName' => 12,
    ),
);

$result = array_map(function($val){
    return $val['categoryId'];
}, $input);

或者创建一个你想要的函数:

function get_values_from_a_key_in_arrays($key, $input){
    return array_map(function($val) use ($key) {
        return $val[$key];
    }, $input);
};

然后使用它:

$result = get_values_from_a_key_in_arrays('categoryId', $array);

它将在 PHP >= 5.3 中工作,其中允许匿名回调。对于早期版本,您需要更早地定义回调并传递其名称而不是匿名函数。