Array merge on multidimensional array

2020-01-29 03:12发布

问题:

Either I'm blind or I can't find this problem anywhere here on SO. Yesterday I had a problem with merging arrays, which I could fix with the help of SO. Today I have, again, a problem with merging arrays, but this time it's with multidimensional Arrays.

I have an array $usergroup['groups'] and an array $usergroup['lang']

$usergroup['groups'] looks like this:

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
        )

)

And $usergroup['lang'] looks like this:

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
        )

)

I want my merged array to look like this:

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?

I've tried several merging functions (array_merge() and array_merge_recursive()) of PHP, the closest result I got was, that the second Array (['lang']) overwrote the first Array (['groups']). To fix that, I tried to remove the empty values on the lang Array (which is always id). But that does not fix it. The code - at the moment - looks like this:

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

The array_merge() on the return command doesn't seem to do anything at all, so I'm probably not gathering the data correctly or I mess something up with the Arrays (forgetting to add [], or I don't know...). I kinda miss the forest for the trees here.

Any suggestions in which direction I could go?

Edit: With the code provided by Pé de Leão I was able to solve the problem. My function now looks like this:

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

And the result is exactly how I wanted it!

回答1:

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


回答2:

maybe its not the smartest but you can try it like this, too:

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;
}

the key of the returned array will be the id of the group in this example.



回答3:

I have never array_merge() with objects before. I suspect you would need to have classes like UNION for it to work (i.e. public data).

  • Assertion: this is your data structure and it won't change much.
  • Assertion: if you had provided var_export() output rather than print_r() in the samples at the top, I could have executed the following (to test it)...
  • It would be better to use a more specific class in the last used cast statement, but I don't know your class hierarchy ~ Usergroup_Model?
  • This answer ignore anything to do with getDefaultLanguage() as that wasn't part of the question.

    $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];
        }
    }
    


回答4:

if(count($array1) >= count($array2)){
    $arr1 = $array1;
    $arr2 = $array2;
}else{
    $arr1 = $array2;
    $arr2 = $array1;
}

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

pr($out);