0

I need to merge (sort of join) two arrays with both same keys, and in result i want to have the values of the first as keys of the second one :

Example :

$keyArray = [
"key1" => "map1",
"key2" => "map1",
"key3" => "map2",
"key4" => "map3"
];

$valuesArray = [
"key1" => "value1",
"key2" => "value2",
"key3" => "value3",
"key4" => "value3"
];

// expected result :

$mappedResultArray = 
[
  "map1" => [
    "value1",
    "value2"
  ],
  "map2" => [
    "value3"
  ],
  "map3" => [
    "valu3"
  ],
];

I know that this is possible by using php loops/foreach through both arrays, But I want to have a solution using PHP array_* functions (array_map, array_merge ....)

user4157124
  • 2,809
  • 13
  • 27
  • 42
  • 4
    Have you tried anything so far? – waterloomatt Feb 04 '22 at 13:42
  • Most of `array_` functions do not consider array keys. This means that you'll have to use something like `array_keys` which is useless. – u_mulder Feb 04 '22 at 13:53
  • `array_combine()` is the closest but it doesn't handle the merging of multiple values for one same key, so typically you would only get `'map1' => 'value2'` instead of `'map1' => ['value1', 'value2']`. So I think you'll probably have to write your own code to do this "merging" if the key already has a value for it. – Patrick Janser Feb 04 '22 at 13:58
  • 2
    `foreach` is the most performant solution because it would be a `O(N)` solution, no need to play smart other way. – ikhvjs Feb 04 '22 at 13:58
  • Equivalent page with one-to-one relationships: [Replace keys in an array based on another lookup/mapping array](https://stackoverflow.com/q/240660/2943403) – mickmackusa Oct 07 '22 at 23:08

3 Answers3

2

You can do this using array_walk with closure see example below :

$keyArray = [ "key1" => "map1", "key2" => "map1", "key3" => "map2", "key4" => "map3" ];

$valueArray = [ "key1" => "value1", "key2" => "value2", "key3" => "value3", "key4" => "value3" ];

function getMergeByKeys($keyArray, $valueArray) {
    $mapped = [];
    array_walk(
        $keyArray, 
        function($key, $value) use ($valueArray, &$mapped) {
            $mapped[$key][] = $valueArray[$value];
        });
    return $mapped;
}

print_r(getMergeByKeys($keyArray, $valueArray));

It will result :

Array
(
    [map1] => Array
        (
            [0] => value1
            [1] => value2
        )

    [map2] => Array
        (
            [0] => value3
        )

    [map3] => Array
        (
            [0] => value3
        )

)
Mohamed23gharbi
  • 1,710
  • 23
  • 28
  • 1
    Nice solution! It's neat. But well, I finally Googled and [using a foreach seems still faster](https://steveclifton-12558.medium.com/array-walk-performance-test-b8cfb11511a8). – Patrick Janser Feb 04 '22 at 14:02
0

A simple foreach is what you need

$keyArray = [
"key1" => "map1",
"key2" => "map1",
"key3" => "map2",
"key4" => "map3"
];


$valuesArray = [
"key1" => "value1",
"key2" => "value2",
"key3" => "value3",
"key4" => "value3"
];


$newArr = [];              
foreach( $keyArray as $key => $value ){
    $newArr[$value][] = $valuesArray[$key]; 
}

print_r($newArr);

This results in:

Array
(
    [map1] => Array
        (
            [0] => value1
            [1] => value2
        )

    [map2] => Array
        (
            [0] => value3
        )

    [map3] => Array
        (
            [0] => value3
        )

)
Angel Deykov
  • 1,199
  • 1
  • 9
  • 15
0
$keys = [ "key1" => "map1", "key2" => "map1", "key3" => "map2", "key4" => "map3" ];
$values = [ "key1" => "value1", "key2" => "value2", "key3" => "value3", "key4" => "value3" ];

$result = array_reduce(
    array_merge_recursive($keys, $values),
    function ($carry, $item) {
      $carry[$item[0]][] = $item[1];
      return $carry;
    }, []
);

print_r($result);
lukas.j
  • 6,453
  • 2
  • 5
  • 24