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

Cal*_*ray 25 php arrays associative-array array-reduce pluck

我确定之前已经问过这个问题,我很抱歉没先找到它.

原始数组:

[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
    )
Run Code Online (Sandbox Code Playgroud)

我希望得到的结果是:print_r(get_values_from_a_key_in_arrays('categoryId',$ array));

[0] => 1
[1] => 5
[2] => 9
Run Code Online (Sandbox Code Playgroud)

我只是在寻找比编写自己的基于foreach的功能更清晰的东西.如果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());
}
Run Code Online (Sandbox Code Playgroud)

Wil*_*III 33

因此,关于高阶 集合/迭代器函数(例如pluck,filter,each,map和friends)的一个很酷的事情是它们可以混合和匹配以组成更复杂的操作集.

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

至于你的测试用例......我们可以用array_reduce实现采摘.我发布的第一个版本依赖于array_map; 但是,我同意@salathe的观点,即array_reduce对于这项任务更为简洁; array_map是一个OK选项,但你最终还是要做更多的工作.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);
Run Code Online (Sandbox Code Playgroud)

选择您喜欢的采摘版本

$preferredPluck = 'pluck_array_reduce'; // or pluck_array_map
Run Code Online (Sandbox Code Playgroud)

对于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());
}
Run Code Online (Sandbox Code Playgroud)

对于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');
}
Run Code Online (Sandbox Code Playgroud)

遗留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;
}
Run Code Online (Sandbox Code Playgroud)

在这里,我们根据我们运行的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';
Run Code Online (Sandbox Code Playgroud)

请注意,没有结尾'?>'.那是因为不需要它.离开它比留下它更好.

FWIW,它看起来像是作为array_column添加到PHP 5.5中.

  • 如果你送我一匹小马,我会投票给你答案. (2认同)

Tad*_*eck 9

映射是您所需要的:

$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);
Run Code Online (Sandbox Code Playgroud)

或者创建一个你想要的功能:

function get_values_from_a_key_in_arrays($key, $input){
    return array_map(function($val) use ($key) {
        return $val[$key];
    }, $input);
};
Run Code Online (Sandbox Code Playgroud)

然后使用它:

$result = get_values_from_a_key_in_arrays('categoryId', $array);
Run Code Online (Sandbox Code Playgroud)

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


Ali*_*xel 6

这没有内置功能,但它通常被称为" 采摘 ".


Raw*_*ode 5

<?php
$a = array(
        array('a' => 1, 'b' => 2),
        array('a' => 2, 'b' => 2),
        array('a' => 3, 'b' => 2),
        array('a' => 4, 'b' => 2)
);

function get_a($v) {
        return $v['a'];
}

var_dump(array_map('get_a', $a));
Run Code Online (Sandbox Code Playgroud)

您可以使用create_function或匿名函数(PHP 5.3> =)

<?php
$a = array(
        array('a' => 1, 'b' => 2),
        array('a' => 2, 'b' => 2),
        array('a' => 3, 'b' => 2),
        array('a' => 4, 'b' => 2)
);

var_dump(array_map(create_function('$v', 'return $v["a"];'), $a));
Run Code Online (Sandbox Code Playgroud)

我将编写一个回调函数,如上所述,然后将其与array_map一起使用.