在关联数组的数组中搜索两个匹配参数
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
可以实现一些东西,但无论如何你必须执行一个双循环。
基于foo
和bar
,我建议您使用临时数组($keys
)作为已创建$newArr
项的索引的单循环解决方案;原数组的元素通过foreach
循环处理,如果存在第一个键为foo
值,第二个键为bar
值的$keys
元素,则当前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 );
编辑: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 );
我有一个循环构建一个关联数组数组,如下所示:
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
可以实现一些东西,但无论如何你必须执行一个双循环。
基于foo
和bar
,我建议您使用临时数组($keys
)作为已创建$newArr
项的索引的单循环解决方案;原数组的元素通过foreach
循环处理,如果存在第一个键为foo
值,第二个键为bar
值的$keys
元素,则当前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 );
编辑: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 );