0

I'm trying to merge these two arrays:

$array1 = array (
  123 => array (
    'minutes_watched' => 192.0,
    'impressions_count' => 18
  ),
  456 => array (
    'minutes_watched' => 200.0,
    'impressions_count' => 20
  )
);

$array2 = array (
  123 => array (
    'ingested_trailers_count' => 3,
    'ingested_shorts_count' => 2,
    'ingested_features_count' => 1
  ),
  456 => array (
    'ingested_trailers_count' => 10,
    'ingested_shorts_count' => 10,
    'ingested_features_count' => 10
  )
);

I would like to end up with this:

$merged = array (
  123 => array (
    'minutes_watched' => 192.0,
    'impressions_count' => 18,
    'ingested_trailers_count' => 3,
    'ingested_shorts_count' => 2,
    'ingested_features_count' => 1
  ),
  456 => array (
    'minutes_watched' => 200.0,
    'impressions_count' => 20,
    'ingested_trailers_count' => 10,
    'ingested_shorts_count' => 10,
    'ingested_features_count' => 10
  )
);

And eventually with this:

$merged = array (
  array(
    'id' => 123 
    'minutes_watched' => 192.0,
    'impressions_count' => 18,
    'ingested_trailers_count' => 3,
    'ingested_shorts_count' => 2,
    'ingested_features_count' => 1
  ),
  array(
    'id' => 456 
    'minutes_watched' => 200.0,
    'impressions_count' => 20,
    'ingested_trailers_count' => 10,
    'ingested_shorts_count' => 10,
    'ingested_features_count' => 10
  )
);

I can't seem to find a concise way of doing this without some clunky for loops. Surely there's some PHP array function that would handle this?

D'Arcy Rail-Ip
  • 11,505
  • 11
  • 42
  • 67

2 Answers2

0

You could try something like this in a single loop. See comments for explanation. Output:

array(2) {
  [0]=>
  array(6) {
    ["minutes_watched"]=>
    float(192)
    ["impressions_count"]=>
    int(18)
    ["ingested_trailers_count"]=>
    int(3)
    ["ingested_shorts_count"]=>
    int(2)
    ["ingested_features_count"]=>
    int(1)
    ["id"]=>
    int(123)
  }
  [1]=>
  array(6) {
    ["minutes_watched"]=>
    float(200)
    ["impressions_count"]=>
    int(20)
    ["ingested_trailers_count"]=>
    int(10)
    ["ingested_shorts_count"]=>
    int(10)
    ["ingested_features_count"]=>
    int(10)
    ["id"]=>
    int(456)
  }
}

Code:

<?php

// Your input array.
$array1 = array (
  123 => array (
    'minutes_watched' => 192.0,
    'impressions_count' => 18
  ),
  456 => array (
    'minutes_watched' => 200.0,
    'impressions_count' => 20
  )
);

$array2 = array (
  123 => array (
    'ingested_trailers_count' => 3,
    'ingested_shorts_count' => 2,
    'ingested_features_count' => 1
  ),
  456 => array (
    'ingested_trailers_count' => 10,
    'ingested_shorts_count' => 10,
    'ingested_features_count' => 10
  )
);

// Output array
$output = [];

// Loop over first array, assuming all keys from $array1
// exist in $array2.
foreach ($array1 as $key => $child)
{
    // Combine the two arrays, preserving keys.
    $merged = $array1[$key] + $array2[$key];
    // Copy key to 'id' element.
    $merged['id'] = $key;
    // Add to output.
    $output[] = $merged;
}

var_dump($output);

/*
array(2) {
  [0]=>
  array(6) {
    ["minutes_watched"]=>
    float(192)
    ["impressions_count"]=>
    int(18)
    ["ingested_trailers_count"]=>
    int(3)
    ["ingested_shorts_count"]=>
    int(2)
    ["ingested_features_count"]=>
    int(1)
    ["id"]=>
    int(123)
  }
  [1]=>
  array(6) {
    ["minutes_watched"]=>
    float(200)
    ["impressions_count"]=>
    int(20)
    ["ingested_trailers_count"]=>
    int(10)
    ["ingested_shorts_count"]=>
    int(10)
    ["ingested_features_count"]=>
    int(10)
    ["id"]=>
    int(456)
  }
}
*/
Ro Achterberg
  • 2,504
  • 2
  • 17
  • 17
0

I ended up with this solution:

  $merged = array_replace_recursive($arrayOne, $arrayTwo);

  $flattened = array_map(function($key, $value) {
      return array_merge($value, [
          'id' => $key
      ]);
  }, array_keys($merged), $merged);

I don't feel great about the array_map portion, however...

D'Arcy Rail-Ip
  • 11,505
  • 11
  • 42
  • 67