0

I'm merging a couple of arrays like this in PHP

//all the other stuff
$array1 = (array) $new;
$array2 =  (array) $info;
$ab = array('a' => $array1, 'b' => $array2);
print_r($ab);

Input objects:

$new = (object) [
    'entries' => [
        (object) [
            'title' => 'Serial - This American Life',
            'id' => 'Serial is a podcast from the creators of This American Life, hosted by Sarah Koenig.'
        ],
        (object) [
            'title' => 'This American Life - This American Life',
            'id' => 'This American Life is a weekly public radio show, heard by 2.2 million people on more than 500 stations.'
        ],
        (object) [
            'title' => 'Real Crime Profile - Real Crime Profile',
            'id' => 'Podcast talking about criminal cases and personality profiling.'
        ]
    ]
];
$info = (object) [
    'entries' => [
        (object) [
            'artistName' => 'This American Life',
            'feedUrl' => 'http://feeds.serialpodcast.org/serialpodcast',
            'primaryGenreName' => 'News & Politics',
            'artworkUrl60' => 'http://is2.mzstatic.com/image/thumb/Music69/v4/70/c9/71/70c97133-f3a8-738e-ea2c-27a6dc7d9731/source/60x60bb.jpg'
        ],
        (object) [
            'artistName' => 'This American Life',
            'feedUrl' => 'http://feed.thisamericanlife.org/talpodcast',
            'primaryGenreName' => 'Personal Journals',
            'artworkUrl60' => 'http://is5.mzstatic.com/image/thumb/Music4/v4/1f/b8/0f/1fb80f69-bd94-8cad-0a2f-b082541d5f64/source/60x60bb.jpg'
        ],
        (object) [
            'artistName' => 'Real Crime Profile',
            'feedUrl' => 'http://feeds.soundcloud.com/users/soundcloud:users:202076064/sounds.rss',
            'primaryGenreName' => 'History',
            'artworkUrl60' => 'http://is5.mzstatic.com/image/thumb/Music69/v4/e4/0d/1e/e40d1efe-f625-8d15-4e2e-706fecead1e8/source/60x60bb.jpg'
        ]
    ]
];

print_r($ab) gives me something like this:

Array
(
    [a] => Array
        (
            [entries] => Array
                (
                    [0] => stdClass Object
                        (
                            [title] => Serial - This American Life
                            [id] => Serial is a podcast from the creators of This American Life, hosted by Sarah Koenig. 
                        )

                    [1] => stdClass Object
                        (
                            [title] => This American Life - This American Life
                            [id] => This American Life is a weekly public radio show, heard by 2.2 million people on more than 500 stations. 
                        )

                    [2] => stdClass Object
                        (
                            [title] => Real Crime Profile - Real Crime Profile
                            [id] => Podcast talking about criminal cases and personality profiling.
                        )

                )

        )

    [b] => Array
        (
            [entries] => Array
                (
                    [0] => stdClass Object
                        (
                            [artistName] => This American Life
                            [feedUrl] => http://feeds.serialpodcast.org/serialpodcast
                            [primaryGenreName] => News & Politics
                            [artworkUrl60] => http://is2.mzstatic.com/image/thumb/Music69/v4/70/c9/71/70c97133-f3a8-738e-ea2c-27a6dc7d9731/source/60x60bb.jpg
                        )

                    [1] => stdClass Object
                        (
                            [artistName] => This American Life
                            [feedUrl] => http://feed.thisamericanlife.org/talpodcast
                            [primaryGenreName] => Personal Journals
                            [artworkUrl60] => http://is5.mzstatic.com/image/thumb/Music4/v4/1f/b8/0f/1fb80f69-bd94-8cad-0a2f-b082541d5f64/source/60x60bb.jpg
                        )

                    [2] => stdClass Object
                        (
                            [artistName] => Real Crime Profile
                            [feedUrl] => http://feeds.soundcloud.com/users/soundcloud:users:202076064/sounds.rss
                            [primaryGenreName] => History
                            [artworkUrl60] => http://is5.mzstatic.com/image/thumb/Music69/v4/e4/0d/1e/e40d1efe-f625-8d15-4e2e-706fecead1e8/source/60x60bb.jpg
                        )

                )

        )

)

This is close to what I'm looking for, but ideally, I'd like to simplify this even more so I don't have an a and b "tree" within this array.

This is what I'm trying to end up with:

Array
(
    [a] => Array
        (
            [entries] => Array
                (
                    [0] => stdClass Object
                        (
                            [title] => Serial - This American Life
                            [id] => Serial is a podcast from the creators of This American Life, hosted by Sarah Koenig. 
                            [artistName] => This American Life
                            [feedUrl] => http://feeds.serialpodcast.org/serialpodcast
                            [primaryGenreName] => News & Politics
                            [artworkUrl60] => http://is2.mzstatic.com/image/thumb/Music69/v4/70/c9/71/70c97133-f3a8-738e-ea2c-27a6dc7d9731/source/60x60bb.jpg
                        )

                    [1] => stdClass Object
                        (
                            [title] => This American Life - This American Life
                            [id] => This American Life is a weekly public radio show, heard by 2.2 million people on more than 500 stations.
                            [artistName] => This American Life
                            [feedUrl] => http://feed.thisamericanlife.org/talpodcast
                            [primaryGenreName] => Personal Journals
                            [artworkUrl60] => http://is5.mzstatic.com/image/thumb/Music4/v4/1f/b8/0f/1fb80f69-bd94-8cad-0a2f-b082541d5f64/source/60x60bb.jpg
                        )

                    [2] => stdClass Object
                        (
                            [title] => Real Crime Profile - Real Crime Profile
                            [id] => Podcast talking about criminal cases and personality profiling.
                            [artistName] => Real Crime Profile
                            [feedUrl] => http://feeds.soundcloud.com/users/soundcloud:users:202076064/sounds.rss
                            [primaryGenreName] => History
                            [artworkUrl60] => http://is5.mzstatic.com/image/thumb/Music69/v4/e4/0d/1e/e40d1efe-f625-8d15-4e2e-706fecead1e8/source/60x60bb.jpg
                        )

                )

        )

)

I've also tried array_merge_recursive($array1['entries'],$array2['entries'], but this give me something like this (6 objects [2 from one array and 4 from the other] instead of 3):

Array
(
    [0] => stdClass Object
        (
            [title] => Serial - This American Life
            [id] => Serial is a podcast from the creators of This American Life, hosted by Sarah Koenig. Serial unfolds one story - a true story - over the course of a whole season. 
        )

    [1] => stdClass Object
        (
            [title] => This American Life - This American Life
            [id] => This American Life is a weekly public radio show, heard by 2.2 million people on more than 500 stations. 
        )

    [2] => stdClass Object
        (
            [title] => Real Crime Profile - Real Crime Profile
            [id] => Podcast talking about criminal cases and personality profiling.
        )

    [3] => stdClass Object
        (
            [artistName] => This American Life
            [feedUrl] => http://feeds.serialpodcast.org/serialpodcast
            [primaryGenreName] => News & Politics
            [artworkUrl60] => http://is2.mzstatic.com/image/thumb/Music69/v4/70/c9/71/70c97133-f3a8-738e-ea2c-27a6dc7d9731/source/60x60bb.jpg
        )

    [4] => stdClass Object
        (
            [artistName] => This American Life
            [feedUrl] => http://feed.thisamericanlife.org/talpodcast
            [primaryGenreName] => Personal Journals
            [artworkUrl60] => http://is5.mzstatic.com/image/thumb/Music4/v4/1f/b8/0f/1fb80f69-bd94-8cad-0a2f-b082541d5f64/source/60x60bb.jpg
        )

    [5] => stdClass Object
        (
            [artistName] => Real Crime Profile
            [feedUrl] => http://feeds.soundcloud.com/users/soundcloud:users:202076064/sounds.rss
            [primaryGenreName] => History
            [artworkUrl60] => http://is5.mzstatic.com/image/thumb/Music69/v4/e4/0d/1e/e40d1efe-f625-8d15-4e2e-706fecead1e8/source/60x60bb.jpg
        )

)

Thoughts on how to merge these into 3 objects?

mickmackusa
  • 43,625
  • 12
  • 83
  • 136
jonmrich
  • 4,233
  • 5
  • 42
  • 94

3 Answers3

1

This is only an example, to explain how you can use function multiArrayCombine from my answer to another question:

foreach( $array['a']['entries'] as &$val ) $val = (array) $val;
foreach( $array['b']['entries'] as &$val ) $val = (array) $val;

$result = multiArrayCombine( $array['a']['entries'], $array['b']['entries'], T_OBJECT_CAST );

$array['a']['entries'] = $result;
unset( $array['b'] );

print_r( $array );

eval.in demo

As I said, this is only an example: the function has the option to return objects but not to analyze it. You can modify it to process also objects and use it directly, without above first two lines.

Community
  • 1
  • 1
fusion3k
  • 11,568
  • 4
  • 25
  • 47
0

Try

for($i=0;$i<count($array1['entries']); $i++){
  $array3['entries'][$i] =(object) ((array) $array1['entries'][$i] + (array) $array2['entries'][$i]);
}
Nabin Kunwar
  • 1,965
  • 14
  • 29
0

The function array_replace_recursive will do what you describe. The problem with array_merge_recursive is that when it encounters sequential arrays, it concatenates the values of the merged arrays, rather than overwriting those entries with the same index. array_replace_recursive is essentially the same thing but always treats arrays as associative and never concatenates them.

http://php.net/manual/en/function.array-replace-recursive.php

Since your leaf nodes are all stdObjects and array_merge_recursive won't merge objects, you will need to convert them to arrays first.

Example:

<?php

$a = [
        'entries' => [
                (object) [
                        'title' => 'Alpha',
                        'id' => 'Alpha ...'
                ],
                (object) [
                        'title' => 'Beta',
                        'id' => 'Beta ...'
                ]
        ]
];

$b = [
        'entries' => [
                (object) [
                        'artistName' => 'Alpha artist',
                        'feedUrl' => 'fdsfsdf'
                ],
                (object) [
                        'artistName' => 'Beta artist',
                        'feedUrl' => 'gfdsgfds'
                ]
        ]
];

function convert_objects($array) {
        array_walk_recursive($array, function(&$value) {
                $value = (array) $value;
        });
        return $array;
}

var_export(array_replace_recursive(convert_objects($a), convert_objects($b)));

Which prints:

array (
  'entries' => 
  array (
    0 => 
    array (
      'title' => 'Alpha',
      'id' => 'Alpha ...',
      'artistName' => 'Alpha artist',
      'feedUrl' => 'fdsfsdf',
    ),
    1 => 
    array (
      'title' => 'Beta',
      'id' => 'Beta ...',
      'artistName' => 'Beta artist',
      'feedUrl' => 'gfdsgfds',
    ),
  ),
)
mooiamaduck
  • 2,066
  • 12
  • 13
  • This doesn't work for me for some reason. I end up with exactly what `$array2` is – jonmrich Feb 12 '16 at 18:36
  • The contents of the `'entries'` array are all `stdObject`s, not arrays. `array_replace_recursive` only merges arrays. You can try converting those values to associative arrays first. – mooiamaduck Feb 12 '16 at 18:38
  • This makes sense, but not sure where in my code I'd need to make the change. This is how I'm making `$array1` for example: `$sxml = simplexml_load_file($url); $json = json_encode($sxml); $jObj = json_decode($json); $new = new stdClass(); foreach ($jObj->entry as $entry) { $s = new stdClass(); $s->title = $entry->title; $s->id = $entry->summary; $new->entries[] = $s; } $array1 = $new;` – jonmrich Feb 12 '16 at 18:42
  • Use `json_decode($json, true);`, which will return all objects as associative arrays instead of `stdObject`s. – mooiamaduck Feb 12 '16 at 18:46
  • This pretty much breaks all of my other code though – jonmrich Feb 12 '16 at 18:48
  • Yes, you would need to refactor any code which treats those items as objects. Your code snippet would become something like `$jObj = json_decode(simplexml_load_file($url), true); $new = ['entries' => []]; foreach($jObj['entry'] as $entry) { $new['entries'][] = ['title' => $entry['title'], ... ] }` – mooiamaduck Feb 12 '16 at 18:52