如何将两个数组映射成一个?

时间:2017-02-28 08:13:59

标签: php arrays

在我合并了两个这样的array_merge($array1, $array2);数组后,就变成了这样,

array(10) {
  [0]=>
  object(stdClass) (2) {
    ["id"]=>
    string(1) "1"
    ["text"]=>
    string(5) "one"
  }
  [1]=>
  object(stdClass) (2) {
    ["id"]=>
    string(1) "2"
    ["text"]=>
    string(8) "two"
  }
  [2]=>
  object(stdClass) (2) {
    ["id"]=>
    string(1) "3"
    ["text"]=>
    string(4) "three"
  }
  [3]=>
  object(stdClass) (2) {
    ["id"]=>
    string(1) "4"
    ["text"]=>
    string(8) "four"
  }
  [4]=>
  object(stdClass) (2) {
    ["id"]=>
    string(1) "5"
    ["text"]=>
    string(3) "five"
  }
  [5]=>
  object(stdClass) (2) {
    ["id"]=>
    string(1) "1"
    ["unit"]=>
    string(1) "0"
  }
  [6]=>
  object(stdClass) (2) {
    ["id"]=>
    string(1) "2"
    ["unit"]=>
    int(0)
  }
  [7]=>
  object(stdClass) (2) {
    ["id"]=>
    string(1) "3"
    ["unit"]=>
    int(0)
  }
  [8]=>
  object(stdClass) (2) {
    ["id"]=>
    string(1) "4"
    ["unit"]=>
    string(1) "0"
  }
  [9]=>
  object(stdClass) (2) {
    ["id"]=>
    string(1) "5"
    ["unit"]=>
    int(1)
  }
}

这意味着两个数组都是字面上合并的。但我想要的是因为两个数组都有一个名为id的共同属性,它具有相同的值,

它应该变成:

array(2) {
  [0]=>
    object(stdClass) (2) {
      ["id"]=>
      string(1) "1"
      ["text"]=>
      string(5) "one"
      ["unit"]=>
      int(0)
    }
    [1]=>
    object(stdClass) (2) {
      ["id"]=>
      string(1) "2"
      ["text"]=>
      string(8) "two"
      ["unit"]=>
      int(2)
    }
  }

请注意,arra1有id,text而array2有id,unit

我确实在这里引用了第一个建议使用array_map的答案,但对我来说,我得到的错误是说参数1不是数组。

Combine two array in to single array with common value

编辑:

试过这个(不起作用):

$array1 = array_walk($array1, function(&$value) { $value = (array) $value; })
$array2 = array_walk($array2, function(&$value) { $value = (array) $value; })
function modifyArray($a, $b)
{
    if (!empty($a) && !empty($b)) {
        return array_merge($a, $b);
    } else if (!empty($a) && empty($b)) {
        return $a;
    }  else if (empty($a) && !empty($b)) {
        return $b;
    }
}

$new = array_map("modifyArray", $array1, $array2);
var_dump($new);

1 个答案:

答案 0 :(得分:1)

将对象转换为数组后,合并两个数组。我将这个数组称为$poorly_merged并从那里开始。在我的演示中,我稍微改组了这个数组,以证明无论子数组的顺序如何,我的代码片段都能正常工作。我的代码也保留了值类型(整数/字符串)。我不知道这是否是最短的解决方案,但我相信它会适用于您的情况。

Demo

<?php
$poorly_merged=array(
    array("id"=>"5","unit"=>1),
    array("id"=>"3","text"=>"three"),
    array("id"=>"1","text"=>"one"),
    array("id"=>"2","text"=>"two"),
    array("id"=>"4","text"=>"four"),
    array("id"=>"5","text"=>"five"),
    array("id"=>"3","unit"=>0),
    array("id"=>"1","unit"=>"0"),
    array("id"=>"2","unit"=>0),
    array("id"=>"4","unit"=>"0")
);

$ids_array=array_unique(array_column($poorly_merged,"id"));  // create array of unique ids
sort($ids_array);   // only necessary if ids are not in order already
$x=0;
foreach($ids_array as $id){
    $well_merged[$x]=array();  // must be declared so array_merge works later
    $q=array("id"=>$id);  // declare the identifying key-value pair (needle) to match
    // create an array only of rows where $q's key-value pairs exist
    $qualifying_array=array_filter(
        $poorly_merged,  // haystack
        function($val)use($q){  // using needle
            if(sizeof(array_intersect_assoc($val,$q))==sizeof($q)){  // if #found = #needles
                return $val;  // it's a keeper
            }
        },
        ARRAY_FILTER_USE_BOTH  // send key-value pairs through the function as $val
    );
    foreach($qualifying_array as $to_be_flattened){
        $well_merged[$x]=array_merge($well_merged[$x],$to_be_flattened);  // merge matches, overwriting duplicate id
    }
    ++$x;
}

echo "<pre>";
var_export($well_merged);
echo "</pre>";

输出:

array (
  0 => 
  array (
    'id' => '1',
    'text' => 'one',
    'unit' => '0',
  ),
  1 => 
  array (
    'id' => '2',
    'text' => 'two',
    'unit' => 0,
  ),
  2 => 
  array (
    'id' => '3',
    'text' => 'three',
    'unit' => 0,
  ),
  3 => 
  array (
    'id' => '4',
    'text' => 'four',
    'unit' => '0',
  ),
  4 => 
  array (
    'id' => '5',
    'unit' => 1,
    'text' => 'five',
  ),
)