Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

php Remove parent level array from set of arrays and merge nodes

I am terrible with manipulating arrays...given this structure I want to remove the top level array and merge all subsets into one flat array:

Array
(
    [0] => Array
        (
            [0] => Array
                (
                    [0] => hey.com
                )

            [1] => Array
                (
                    [0] => you.com
                )
        )
    [1] => Array
        (
            [0] => Array
                (
                    [0] => this.com
                )

            [1] => Array
                (
                    [0] => rocks.com
                )
        )
)

to desired structure:

Array
    (
        [0] => hey.com
        [1] => you.com
        [2] => this.com
        [3] => rocks.com
    )

Speed is essential - we will be dealing with hundreds of thousands of results

like image 877
Jared Eitnier Avatar asked Dec 17 '12 19:12

Jared Eitnier


People also ask

How to combine multidimensional array in php?

The array_merge_recursive() function merges one or more arrays into one array. The difference between this function and the array_merge() function is when two or more array elements have the same key. Instead of override the keys, the array_merge_recursive() function makes the value as an array.

How do you delete one level of an array?

The array_shift() function removes the first element from an array, and returns the value of the removed element.

What is array_ column in php?

PHP array_column() Function The array_column() function returns the values from a single column of the input array and identified by the column_key. Optionally, you can pass index_key to index the values in the returned array by the values from the index_key column of the input array.


4 Answers

$flat = call_user_func_array('array_merge', $arr);

That will flatten the array by exactly one level. It will take the sample input you provided, and produce the desired output you asked for.

*note - the question was edited after this answer was posted. The question previously requested the following desired result:

Array
(
    [0] => Array
        (
            [0] => hey.com
            [1] => you.com
            [2] => this.com
            [3] => rocks.com
        )

)

Which is what the above array_merge() answer provides.

Make sure:

  1. your parent array uses numeric indexes
  2. the parent array has at least one child element, otherwise you'll get a php error due to array_merge complaining of no arguments.

For those who wonder how it works:

// with 
$arr = [ [1,2,3], [4,5,6] ];
// call_user_func_array('array_merge', $arr) is like calling
array_merge($arr[0], $arr[1]);

// and with 
$arr = [ [1,2,3], [4,5,6], [7,8,9] ];
// then it's like:
array_merge($arr[0], $arr[1], $arr[2]);
// and so on...

If you're using php 5.6+, the splat operator (...) can be more readable way of doing this:

$flat = array_merge(...$arr);

If you want to flatten by more than a single level, you can either use multiple nested array_merge() calls, or if you want to recursively fully flatten the structure:

// This is a great option if you don't know what depth the structure may be,
// or if the structure may contain different arrays with different depths.
$flat = iterator_to_array(new RecursiveIteratorIterator(new RecursiveArrayIterator($arr)));
like image 111
goat Avatar answered Nov 01 '22 19:11

goat


You can use RecursiveArrayIterator

$it = new RecursiveIteratorIterator(new RecursiveArrayIterator($data));
$list = iterator_to_array($it,false);
var_dump($list);

Output

array (size=4)
  0 => string 'hey.com' (length=7)
  1 => string 'you.com' (length=7)
  2 => string 'this.com' (length=8)
  3 => string 'rocks.com' (length=9)

See Simple Demo

like image 40
Baba Avatar answered Nov 01 '22 19:11

Baba


<?php
//Very simple recoursive solution
$array = array(
    array(
        array('hey.com'),
        array('you.com')
    ),
    array(
        array('this.com'),
        array('rocks.com'),
        array(
            array('its.com'),
            array(
                array('soo.com'),
                array('deep.com')
            )
        )
    )
);

function deepValues(array $array) {
    $values = array();
    foreach($array as $level) {
        if (is_array($level)) {
            $values = array_merge($values,deepValues($level));
        } else {
            $values[] = $level;
        }
    }
    return $values;
}

$values = deepValues($array);
echo "<pre>";
print_r($values);
echo "</pre>";
?>

I dont know how to get arral like this, but this solution is get only values.

[edited] Im sorry, its sweetest:

function deepValues(array $array, array &$values) {
    foreach($array as $level) {
        if (is_array($level)) {
            deepValues($level, $values);
        } else {
            $values[] = $level;
        }
    }
}
like image 34
DevMetal91 Avatar answered Nov 01 '22 17:11

DevMetal91


If the values are always at the same level of depth you could indeed use array_merge:

$array = [                                                                                                                                                                                                                                 
    [
        ['hey.com'],
        ['you.com'],
    ],                                                                                                                                                                                                                
    [
        ['this.com'],
        ['rocks.com'],
    ],                                                                                                                                                                                                             
];

print_r(array_merge(... array_merge(... $array)));

Getting:

Array
(
    [0] => hey.com
    [1] => you.com
    [2] => this.com
    [3] => rocks.com
)
like image 36
Mark Avatar answered Nov 01 '22 17:11

Mark