Объединение массивов на основе значения ключа

у меня есть два массива массивов, которые имеют id key, и я хотел бы объединить данные вместе на основе ключа и значения ключа этого массива. Данные будут выглядеть примерно так:

    $color = [
        ['id' => 1, 'color' => 'red'],
        ['id' => 2, 'color' => 'green'],
        ['id' => 3, 'color' => 'blue'],
    ];

    $size = [
        ['id' => 1, 'size' => 'SM'],
        ['id' => 2, 'size' => 'XL'],
        ['id' => 3, 'size' => 'MD'],
        ['id' => 4, 'size' => 'LG'],
    ];

    $combined = [
        ['id' => 1, 'color' => 'red', 'size' => 'SM'],
        ['id' => 2, 'color' => 'green', 'size' => 'XL'],
        ['id' => 3, 'color' => 'blue', 'size' => 'MD'],
        ['id' => 4, 'size' => 'LG'],
    ];

есть ли особенно эффективная функция или трюк для обработки чего-то подобного? Или я должен просто перебирать элементы одного массива и передавать содержимое другому?

Я также использую Laravel, и данные являются результатом красноречивого запроса, поэтому я также могу использовать коллекции, если это сделает код более чистым.

7 ответов


можно использовать array_replace_recursive для объединения массивов в вашей конкретной ситуации.

$color = array(
    array('id' => 1, 'color' => 'red'),
    array('id' => 2, 'color' => 'green'),
    array('id' => 3, 'color' => 'blue'),
);

$size = array(
    array('id' => 1, 'size' => 'SM'),
    array('id' => 2, 'size' => 'XL'),
    array('id' => 3, 'size' => 'MD'),
    array('id' => 4, 'size' => 'LG'),
);

$merged = array_replace_recursive($color, $size);

выход:

array(4) {
  [0]=>
  array(3) {
    ["id"]=>
    int(1)
    ["color"]=>
    string(3) "red"
    ["size"]=>
    string(2) "SM"
  }
  [1]=>
  array(3) {
    ["id"]=>
    int(2)
    ["color"]=>
    string(5) "green"
    ["size"]=>
    string(2) "XL"
  }
  [2]=>
  array(3) {
    ["id"]=>
    int(3)
    ["color"]=>
    string(4) "blue"
    ["size"]=>
    string(2) "MD"
  }
  [3]=>
  array(2) {
    ["id"]=>
    int(4)
    ["size"]=>
    string(2) "LG"
  }
}

Примечание: я использовал традиционный макет массива, потому что моя версия PHP еще не поддерживает новую:)

второй вариант

вы также можете использовать array_map. Это позволит вам добавить столько массивов, сколько вы хотите с немного щипание.

$merged = array_map(function ($c, $s) {
    return array_merge($c, $s);
}, $color, $size);

var_dump($merged); // See output above

использовать array_replace_recursive для легкого и быстрого пути

array_replace_recursive($color, $size)

лучший способ использования цикла. Сначала вычислите максимальный массив, подсчитав это число, запустите цикл. Это сработает.


попробуй:

$out = array();
foreach ($size as $key => $value){
    if(!isset($color[$key])) { $color[$key] = array(); }  
    $out[] = array_merge((array)$value,(array)$color[$key]);
}

выход:

Array
(
    [0] => Array
        (
            [id] => 1
            [size] => SM
            [color] => red
        )

    [1] => Array
        (
            [id] => 2
            [size] => XL
            [color] => green
        )

    [2] => Array
        (
            [id] => 3
            [size] => MD
            [color] => blue
        )

    [3] => Array
        (
            [id] => 4
            [size] => LG
        )

)

простой вложенный цикл решил бы цель.

foreach($size as $key => $value1) {
    foreach($color as $value2) {
        if($value1['id'] === $value2['id']){
            $size[$key]['title'] = $value2['color'];
        }               
    }
}
echo '<pre>';
print_r($size);

выход:

   Array
  (
   [0] => Array
    (
        [id] => 1
        [size] => SM
        [title] => red
    )

  [1] => Array
    (
        [id] => 2
        [size] => XL
        [title] => green
    )

[2] => Array
    (
        [id] => 3
        [size] => MD
        [title] => blue
    )

[3] => Array
    (
        [id] => 4
        [size] => LG
    )

)

Я бы предложил использовать коллекции laravel, так как этот вопрос имеет тег laravel.

$color = collect(
    ['id' => 1, 'color' => 'red'],
    ['id' => 2, 'color' => 'green'],
    ['id' => 3, 'color' => 'blue']
);

$size = collect(
    ['id' => 1, 'size' => 'SM'],
    ['id' => 2, 'size' => 'XL'],
    ['id' => 3, 'size' => 'MD'],
    ['id' => 4, 'size' => 'LG']
);

$combined = $color->merge($size);

Pure php решение использовать array_replace_recursive такой:

array_replace_recursive(
  array_combine(array_column($color, "id"), $color),
  array_combine(array_column($size, "id"), $size)
);

вы должны заметить, что array_replace_recursive объединить массивы по ключам. Итак, если вы получаете такие данные из базы данных:

$color = [
    ['id' => 1, 'color' => 'red'],
    ['id' => 2, 'color' => 'red']
];

$size = [
    ['id' => 2, 'size' => 'SM']
];

array_replace_recursive вернутся повреждены слияние:

$combined = [
    ['id' => 2, 'color' => 'red', 'size' => 'SM'],
    ['id' => 2, 'color' => 'red']
];

решение состоит в том, чтобы объединить array_replace_recursive С array_column и array_combine для объединения массивов по их