举个例子,我有以下数组:
$groups = [
'group1' => [
'a' => 'able',
'b' => 'baker',
'd' => 'dog'
],
'group2' => [
'a' => 'able',
'c' => 'charlie',
'd' => 'dog'
],
'group3' => [
'c' => 'charlie',
'e' => 'easy'
]
]
我想完全删除任何重复的项目;从上面的例子中,我想得到以下结果:
[
'group1' => [
'b' => 'baker'
],
'group2' => [
],
'group3' => [
'e' => 'easy'
]
]
我目前的代码如下:
foreach ($groups as $group_id => &$group_things) {
foreach ($group_things as $thing_id => $thing) {
foreach ($groups as $search_group_id => &$search_things) {
if ($search_group_id == $group_id) {
continue;
}
if (array_key_exists($thing_id, $search_things)) {
unset(
$group_things[$thing_id],
$search_things[$thing_id]
);
$ungrouped_things[$thing_id] = $thing;
}
}
}
}
这是有效的,但我的同事们已经完全劝告。是否有更优雅/更少循环的前进方式?
答案 0 :(得分:0)
不确定是否有一种超级简单的方法可以做到这一点,即作为一个班轮。但是你可以稍微缩短你的代码并使其更加模块化,这可能会给你积分:
function values($array) {
return iterator_to_array(
new RecursiveIteratorIterator(
new RecursiveArrayIterator($array)
),false
);
}
function duplicates($array) {
return array_keys(
array_filter(
array_count_values(values($array)),
function($v) {
return $v>1;
}
)
);
}
然后,每次需要过滤2x数组时,您需要做的就是:
$duplicates = duplicates($groups);
foreach($groups as &$group) {
$group = array_diff($group,$duplicates);
}
仅供参考:我通过引用传递$group
,因为它很性感,但在for循环中不一定是个好主意。
此外,如果您从数据库获取此数据,则最好在查询语句中执行此操作。
答案 1 :(得分:0)
foreach($groups as &$group)
foreach($groups as &$group2)
{
if ($group != $group2) {
$tmp = array_diff_assoc($group2, $group);
$group = array_diff_assoc($group, $group2);
$group2 = $tmp;
}
}
print_r($groups);
结果:
Array
(
[group1] => Array
(
[b] => baker
)
[group2] => Array
(
)
[group3] => Array
(
[e] => easy
)
)
ps:它不会使用超过2个重复项,但此代码将执行此操作
foreach($groups as &$group)
{
$tmp = $group;
foreach($groups as &$group2)
{
if ($group != $group2) {
$tmp = array_diff_assoc($tmp, $group2);
$group2 = array_diff_assoc($group2, $group);
}
}
$group = $tmp;
}
print_r($groups);