多维数组上的数组合并

时间:2013-07-25 06:12:23

标签: php arrays multidimensional-array

无论是我是盲人还是我无法在这里找到这个问题。 昨天我遇到了合并数组的问题,我可以在SO的帮助下解决这个问题。今天我再次遇到了合并数组的问题,但这次是使用多维数组。

我有一个数组$usergroup['groups']和一个数组$usergroup['lang']

$usergroup['groups']看起来像这样:

Array
(
    [0] => Usergroup_Model Object
        (
            [id] => 1
            [deleted] => 0
        )

    [1] => Usergroup_Model Object
        (
            [id] => 2
            [deleted] => 0
        )

    [2] => Usergroup_Model Object
        (
            [id] => 3
            [deleted] => 0
        )

)

$usergroup['lang']看起来像这样:

Array
(
    [0] => Usergroup_Model Object
        (
            [id] => 
            [id_usergroup] => 1
            [name] => Administratoren
            [id_lang] => 1
        )

    [1] => Usergroup_Model Object
        (
            [id] => 
            [id_usergroup] => 2
            [name] => Benutzer
            [id_lang] => 1
        )

    [2] => Usergroup_Model Object
        (
            [id] => 
            [id_usergroup] => 3
            [name] => Gäste
            [id_lang] => 1
        )

)

我希望我的合并数组看起来像这样:

Array
(
    [0] => Usergroup_Model Object
        (
            [id] => 1
            [id_usergroup] => 1
            [name] => Administratoren
            [id_lang] => 1
            [deleted] => 0
        )

    [1] => Usergroup_Model Object
        (
            [id] => 2
            [id_usergroup] => 2
            [name] => Benutzer
            [id_lang] => 1
            [deleted] => 0
        )

    [2] => Usergroup_Model Object
        (
            [id] => 3
            [id_usergroup] => 3
            [name] => Gäste
            [id_lang] => 1
            [deleted] => 0
        )

)

What have I tried?

我已经尝试了PHP的几个合并函数(array_merge()array_merge_recursive()),我得到的最接近的结果是,第二个数组(['lang'])覆盖了第一个数组({ {1}})。为了解决这个问题,我尝试删除['groups']数组(总是lang)上的空值。但这并没有解决它。代码 - 目前 - 看起来像这样:

id

return命令上的array_merge()似乎根本没有做任何事情,所以我可能没有正确地收集数据或者我用数组弄乱了一些东西(忘记添加[],或者我不知道我知道...)。我有点想念这里的树林。

我可以向哪个方向提出建议?

编辑:使用PédeLeão提供的代码,我能够解决问题。我的功能现在看起来像这样:

public static function getAll()
{
  $usergroup['groups'] = self::find();
  $usergroup['lang'] = self::findInTable(array(
    'id_lang' => Language_Model::getDefaultLanguage()
  ), self::dbTranslationTable);
  foreach ($usergroup as $ug) {
    $ug = array_filter($ug, function($val) {
      return $val != '';
    });
  }
  return array_merge($ug);
}

结果正是我想要的!

4 个答案:

答案 0 :(得分:5)

$out = array();
foreach ($arr1 as $key => $value){
    $out[] = (object)array_merge((array)$arr2[$key], (array)$value);
}
print_r($out)

答案 1 :(得分:0)

也许它不是最聪明的,但你也可以这样尝试:

public static function getAll()
{
  $groups = self::find();
  $lang = self::findInTable(array(
    'id_lang' => Language_Model::getDefaultLanguage()
  ), self::dbTranslationTable);

  $n = array();
  foreach($groups as $g) {
      $id = $g['id'];
      $n[$id] = $g;
  }

  foreach($lang as $a) {
      $id = $a['id_usergroup'];
      if(!isset($n[$id])){ $n[$id] = array(); }
      $n[$id]['id_usergroup'] = $a['id_usergroup'];
      $n[$id]['name'] = $a['name'];
      $n[$id]['id_lang'] = $a['id_lang'];
  }

  return $n;
}

返回数组的键将是此示例中组的id。

答案 2 :(得分:0)

我之前从未使用过带有对象的array_merge()。我怀疑你需要像UNION这样的类才能使它工作(即公共数据)。

  • 断言:这是您的数据结构,不会有太大变化。
  • 断言:如果您在顶部的示例中提供了var_export()输出而不是print_r(),我可以执行以下操作(以测试它)......
  • 最后在上次使用的演员语句中使用更具体的类会更好,但我不知道你的类层次结构~Usergroup_Model?
  • 这个答案忽略了与getDefaultLanguage()的任何关系,因为这不是问题的一部分。

    $ITEMS=count($usergroup['groups']);
    $out=array();
    for($i=0; $i<$ITEMS; $i++) {
        if(isset($usergroup['lang'][$i])) {
            $out[]=(object)array_merge((array)$usergroup['groups'][$i], (array)$usergroup['lang'][$i]);
        } else {
            $out[]=$usergroup['groups'][$i];
        }
    }
    

答案 3 :(得分:0)

const arr1 = [{id:1,name:'AB'}, {id:2,name:'CD'}]
const arr2 = [{id:3,name:'EF'}, {id:2,name:'CD'}]

const flatten = a => [].concat.apply([], a)
const noDuplicateProps = (a, b) => Object.keys(a).some(k => a[k] === b[k])

const combineAndDeDup = (...arrs) => {
  
  return flatten(arrs).reduce((acc, item) => {
    const uniqueItem = acc.findIndex(i => noDuplicateProps(i, item)) === -1
    
    if (uniqueItem) return acc.concat([ item ])
    
    return acc
  }, [])
}


const deDuped = combineAndDeDup(arr1, arr2)
const megaDeDuped = combineAndDeDup(arr1, arr2, arr1, arr1, arr2, arr1)

console.log(deDuped)
console.log(megaDeDuped)