1

我有一个数组,它由不确定数量的数组组成,递归地(n 级深)。每个数组可能包含一个name键。我想创建这些值的唯一列表。

例子

假设数组是:

$bigArray = array(
    'name'=>'one', 
    'something'=>array(
        'name'=>'two', 
        'subthing'=>array('name'=>'three')
    ), 
    'anotherthing'=>array('name'=>'one')
);

预期的结果是:

$uniques = array('one', 'two', 'three') // All the 'name' keys values and without duplicates.

这是我的尝试

我的方法是使用array_walk_recursive传递一个$uniques数组作为参考,并允许函数更新该值:

$uniques = array();

function singleOut($item, $key, &$uniques) {
    if ($key == 'name' && !in_array($itm,$uniques,true) )
        $uniques[] = $item;
}

array_walk_recursive($bigArray, 'singleOut', $uniques);

但是,它对我不起作用。

4

3 回答 3

0

你也可以array_unique在这个上使用。例子:

$uniques = array();
array_walk_recursive($bigArray, function($val, $key) use (&$uniques){
    if($key == 'name') {
        $uniques[] = $val;
    }
});

$uniques = array_unique($uniques); // unique values
于 2014-09-03T00:48:07.347 回答
0

您的小提琴几乎是正确的 - 问题是,用户参数仅在相同级别的递归中通过引用给出。您需要使用间接引用:

$bigArray = array(
    'name'=>'one', 
    'something'=>array(
        'name'=>'two', 
        'subthing'=>array('name'=>'three')
    ), 
    'anotherthing'=>array('name'=>'one')
);

function singleOut($item, $key, $indirect) {
    $uniques=&$indirect[0];
    if ($key == 'name' && !in_array($item,$uniques,true) ) $uniques[] = $item;

}

$uniques = array();
$indirect = array(&$uniques);
array_walk_recursive($bigArray, 'singleOut', $indirect);
print_r($uniques);

编辑:

小提琴在这里

于 2014-09-03T01:00:24.207 回答
0

为避免在in_array()内部进行检查array_walk_recursive(),您可以将name值作为键存储在输出数组中。这将通过覆盖以前的相同键来有效地消除重复项。完成array_walk_recursive()后,您可以使用array_keys()将数据从键移动到值。

代码:(演示

$bigArray=[
    'name'=>'one', 
    'something'=>[
        'name'=>'two', 
        'subthing'=>['name'=>'three']
    ], 
    'anotherthing'=>['name'=>'one']
];
array_walk_recursive($bigArray,function($v,$k)use(&$uniques){
    if($k==='name')
        $uniques[$v]='';
});
var_export(array_keys($uniques));

输出:

array (
  0 => 'one',
  1 => 'two',
  2 => 'three',
)

因为array_unique()在某些情况下可能会很慢,所以使用array_keys()通常应该执行得更快。也就是说,如果微优化是一个问题,那么您应该使用您的实际数据和您的特定环境进行基准测试,并为您的项目选择最佳方法。

正如我在 Ghost 回答下的评论中提到的那样,===对多维数组中的键进行严格比较是一个好习惯,因为如果您正在寻找一个字符串,但遇到一个0键,那么 PHP 的类型杂耍“功能”将提供意想不到的结果。

这是我讨论和演示此行为的页面:类型杂耍而进行松散的比较会产生不需要的结果

于 2017-09-08T02:43:42.597 回答