从深层数组中任何位置存在的特定键中生成一个唯一的值列表



我有一个数组,它由数量不确定的数组组成,递归(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);

但是,它对我不起作用。

您也可以在这个上使用array_unique。示例:

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

你的fiddle几乎是对的——问题是,用户参数只在相同级别的递归中通过引用给出。您需要使用间接引用:

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

编辑:

Fiddle在这里

为了避免在array_walk_recursive()内部进行in_array()检查,可以将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的类型转换"功能"会提供意想不到的结果。

这是一个我讨论和演示这种行为的页面:在进行松散比较时进行类型杂耍会产生不想要的结果

相关内容

  • 没有找到相关文章

最新更新