在关联数组数组中搜索两个匹配的参数


Searching an array of associate arrays for two matching parameters

我有一个循环,它构建了一个关联数组数组,如下所示:

array(
    'foo' => '',
    'bar' => '',
    'thingys' => array()
)

在循环的每次迭代中,我想在数组中搜索一个关联数组,该数组的"foo"和"bar"属性与当前关联数组的属性匹配。如果存在,我想将当前关联数组的 thingys 属性附加到匹配项中。否则附加整个内容。我知道如何使用 for 循环执行此操作,但我想知道是否有更简单的方法可以使用数组函数执行此操作。我在 php 5.3 上。

<?php 
$arr = array(
    array(
        'foo' => 1,
        'bar' => 2,
        'thing' => 'apple'
    ),
    array(
        'foo' => 1,
        'bar' => 2,
        'thing' => 'orange'
    ),
    array(
        'foo' => 2,
        'bar' => 2,
        'thing' => 'apple'
    ),
);
$newArr = array();
for ($i=0; $i < count($arr); $i++) {
    $matchFound = false;
    for ($j=0; $j < count($newArr); $j++) { 
        if ($arr[$i]['foo'] === $newArr[$j]['foo'] && $arr[$i]['bar'] === $newArr[$j]['bar']) {
            array_push($newArr[$j]['thing'], $arr[$i]['things']);
            $matchFound = true;
            break;
        }
    }
    if (!$matchFound) {
        array_push($newArr,
            array(
                'foo' => $arr[$i]['foo'],
                'bar' => $arr[$i]['bar'],
                'things' => array($arr[$i]['thing'])
            )
        );
    }
}
/*Output
$newArr = array(
    array(
        'foo' => 1,
        'bar' => 2,
        'things' => array('orange', 'apple')
    ),
    array(
        'foo' => 2,
        'bar' => 2,
        'things' => array('apple')
    ),
)
*/
 ?>
我不知道通过

内置函数是否可以,但我认为不是。有些东西可以通过 array_map 来实现,但无论如何你必须执行双循环。

我建议你一个单循环解决方案,使用一个临时数组($keys)作为已经创建的$newArr项的索引,基于foobar;原始数组的元素通过foreach循环处理,如果存在一个$keys元素,第一个键作为foo值,第二个键作为bar值, 然后将当前thing值添加到返回的键索引 $newArr 中,否则将创建一个新的 $newArray 元素。

$newArr = $keys = array();
foreach( $arr as $row )
{
    if( isset( $keys[$row['foo']][$row['bar']] ) )
    { $newArr[$keys[$row['foo']][$row['bar']]]['thing'][] = $row['thing']; }
    else
    {
        $keys[$row['foo']][$row['bar']] = array_push( $newArr, $row )-1;
        $newArr[$keys[$row['foo']][$row['bar']]]['thing'] = array( $row['thing'] );
    }
}
unset( $keys );

3v4l.org 演示

编辑:array_map变体

这与上面的解决方案相同,使用array_map而不是foreach循环。请注意,您的原始代码也可以通过这种方式进行转换。

$newArr = $keys = array();
function filterArr( $row )
{
    global $newArr, $keys;
    if( isset( $keys[$row['foo']][$row['bar']] ) )
    { $newArr[$keys[$row['foo']][$row['bar']]]['thing'][] = $row['thing']; }
    else
    {
        $keys[$row['foo']][$row['bar']] = array_push( $newArr, $row )-1;
        $newArr[$keys[$row['foo']][$row['bar']]]['thing'] = array( $row['thing'] );
    }
}
array_map( 'filterArr', $arr );

3v4l.org 演示