PHP - How to merge arrays inside array

前端 未结 4 1536
灰色年华
灰色年华 2020-11-27 04:24

How to merge n number of array in php. I mean how can I do the job like :
array_merge(from : $result[0], to : $result[count($result)-1])
OR<

相关标签:
4条回答
  • 2020-11-27 04:31

    Try this

    $result = array_merge($array1, $array2);
    

    Or, instead of array_merge, you can use the + op which performs a union:

    $array2 + array_fill_keys($array1, '');
    
    0 讨论(0)
  • 2020-11-27 04:44

    array_merge can take variable number of arguments, so with a little call_user_func_array trickery you can pass your $result array to it:

    $merged = call_user_func_array('array_merge', $result);
    

    This basically run like if you would have typed:

    $merged = array_merge($result[0], $result[1], .... $result[n]);
    

    Update:

    Now with 5.6, we have the ... operator to unpack arrays to arguments, so you can:

    $merged = array_merge(...$result);
    

    And have the same results. *

    * The same results as long you have integer keys in the unpacked array, otherwise you'll get an E_RECOVERABLE_ERROR : type 4096 -- Cannot unpack array with string keys error.

    0 讨论(0)
  • I really liked the answer from complex857 but it didn't work for me, because I had numeric keys in my arrays that I needed to preserve.

    I used the + operator to preserve the keys (as suggested in PHP array_merge with numerical keys) and used array_reduce to merge the array.

    So if you want to merge arrays inside an array while preserving numerical keys you can do it as follows:

    <?php
    $a = [
        [0 => 'Test 1'],
        [0 => 'Test 2', 2 => 'foo'],
        [1 => 'Bar'],
    ];    
    
    print_r(array_reduce($a, function ($carry, $item) { return $carry + $item; }, []));
    ?>
    

    Result:

    Array
    (
        [0] => Test 1
        [2] => foo
        [1] => Bar
    )
    
    0 讨论(0)
  • 2020-11-27 04:45

    If you would like to:

    • check that each param going into array_merge is actually an array
    • specify a particular property within one of the arrays to merge by

    You can use this function:

    function mergeArrayofArrays($array, $property = null)
    {
        return array_reduce(
            (array) $array, // make sure this is an array too, or array_reduce is mad.
            function($carry, $item) use ($property) {
    
                $mergeOnProperty = (!$property) ?
                        $item :
                        (is_array($item) ? $item[$property] : $item->$property);
    
                return is_array($mergeOnProperty)
                    ? array_merge($carry, $mergeOnProperty)
                    : $carry;
        }, array()); // start the carry with empty array
    }
    

    Let's see it in action.. here's some data:

    Simple structure: Pure array of arrays to merge.

    $peopleByTypesSimple = [
        'teachers' => [
                0  => (object) ['name' => 'Ms. Jo', 'hair_color' => 'brown'],
                1  => (object) ['name' => 'Mr. Bob', 'hair_color' => 'red'],
        ],
    
        'students' => [
                0  => (object) ['name' => 'Joey', 'hair_color' => 'blonde'],
                1  => (object) ['name' => 'Anna', 'hair_color' => 'Strawberry Blonde'],
        ],
    
        'parents' => [
                0  => (object) ['name' => 'Mr. Howard', 'hair_color' => 'black'],
                1  => (object) ['name' => 'Ms. Wendle', 'hair_color' => 'Auburn'],
        ],
    ];
    

    Less simple: Array of arrays, but would like to specify the people and ignore the count.

    $peopleByTypes = [
        'teachers' => [
            'count' => 2,
            'people' => [
                0  => (object) ['name' => 'Ms. Jo', 'hair_color' => 'brown'],
                1  => (object) ['name' => 'Mr. Bob', 'hair_color' => 'red'],
            ]
        ],
    
        'students' => [
            'count' => 2,
            'people' => [
                0  => (object) ['name' => 'Joey', 'hair_color' => 'blonde'],
                1  => (object) ['name' => 'Anna', 'hair_color' => 'Strawberry Blonde'],
            ]
        ],
    
        'parents' => [
            'count' => 2,
            'people' => [
                0  => (object) ['name' => 'Mr. Howard', 'hair_color' => 'black'],
                1  => (object) ['name' => 'Ms. Wendle', 'hair_color' => 'Auburn'],
            ]
        ],
    ];
    

    Run it

    $peopleSimple = mergeArrayofArrays($peopleByTypesSimple);
    $people = mergeArrayofArrays($peopleByTypes, 'people');
    

    Results - Both return this:

    Array
    (
        [0] => stdClass Object
            (
                [name] => Ms. Jo
                [hair_color] => brown
            )
    
        [1] => stdClass Object
            (
                [name] => Mr. Bob
                [hair_color] => red
            )
    
        [2] => stdClass Object
            (
                [name] => Joey
                [hair_color] => blonde
            )
    
        [3] => stdClass Object
            (
                [name] => Anna
                [hair_color] => Strawberry Blonde
            )
    
        [4] => stdClass Object
            (
                [name] => Mr. Howard
                [hair_color] => black
            )
    
        [5] => stdClass Object
            (
                [name] => Ms. Wendle
                [hair_color] => Auburn
            )
    
    )
    

    Extra Fun: If you want to single out one property in an array or object, like "name" from an array of people objects(or associate arrays), you can use this function

    function getSinglePropFromCollection($propName, $collection, $getter = true)
    {
        return (empty($collection)) ? [] : array_map(function($item) use ($propName) {
            return is_array($item) 
                ? $item[$propName] 
                : ($getter) 
                    ? $item->{'get' . ucwords($propName)}()
                    : $item->{$propName}
        }, $collection);
    }
    

    The getter is for possibly protected/private objects.

    $namesOnly = getSinglePropFromCollection('name', $peopleResults, false);

    returns

    Array
    (
        [0] => Ms. Jo
        [1] => Mr. Bob
        [2] => Joey
        [3] => Anna
        [4] => Mr. Howard
        [5] => Ms. Wendle
    )
    
    0 讨论(0)
提交回复
热议问题