1

I have searched alot, but can't find the exact similair question. The built-in function in PHP don't do what I'm looking for. Note: array_merge_recursively(...) came close, but didn't keep the indexes.

I have for example to arrays in PHP (json visualization):

[
    ["1-6-13", 10],
    ["30-6-13", 13],
    ["20-9-13", 28]
]

and:

[
    ["18-2-13", 7],
    ["30-6-13", 9]
]

And I want to merge those two, based on their date. However not every date matches the other one, it is important that the value of array 1 will be on index 1, and the value of array 2 must be appended to index 2. The values which don't exists must be for instance null.

So the desired result would look like:

[
    ["18-2-13", null, 7],
    ["1-6-13", 10, null],
    ["30-6-13", 13, 9],
    ["20-9-13", 28, null]
]

I hope someone can help me out!

Tim
  • 5,137
  • 7
  • 32
  • 62
  • Why not use the date as a key rather than an array value since that seems to be what you are trying to aggregate on? That would make this task trivial with `array_merge_recursive()` – Mike Brant Jun 14 '13 at 18:59

2 Answers2

3

You can first get a collection of all dates like this:

$dates = array_merge(array_map('reset', $data1), array_map('reset', $data2));

This collection includes duplicates, but we don't really care (we could remove them with array_unique if that was a problem).

Side note: if running PHP >= 5.5 it would be preferable to do array_column($arr, 0) instead of array_map('reset', $arr).

Then project that into an array of arrays, using the dates as keys:

$result = array_fill_keys($dates, array(null, null, null));

And fill it up with data:

foreach($data1 as $pair) {
    list($date, $num) = $pair;
    $result[$date][0] = $date;
    $result[$date][1] = $num;
}

foreach($data2 as $pair) {
    list($date, $num) = $pair;
    $result[$date][0] = $date;
    $result[$date][2] = $num;
}

Of course the above can easily be generalized for an arbitrary number of arrays with a loop.

Finally, if you want the $result to be numerically indexed then lose the dates that were used as keys:

$result = array_values($result);

See it in action.

Jon
  • 396,160
  • 71
  • 697
  • 768
1

You could do this. The benefit is that you only loop through the arrays once:

$dates = array();
foreach( $array1 as $val ) {
    $dates[$val[0]] = array( $val[0], $val[1], null );
}
foreach( $array2 as $val) {
    $dates[$val[0]][0] = $val[0];
    $dates[$val[0]][1] = isset( $dates[$val[0]][1] ) ? $dates[$val[0]][1] : null;
    $dates[$val[0]][2] = $val[1];
}
Precastic
  • 3,172
  • 1
  • 19
  • 27