Toby
Toby

Reputation: 8792

Converting a multidimensional array into a single dimensional one

If from a function I am returned a multidimensional array like this..

array(0 => array('a' => 5), 1 => array('a' => 8))

But I just really need the contents of the key 'a' what is the best way for me to convert.

Current I have been doing something like..

$new_array = array();

foreach ($multi_array AS $row) {
    $new_array[] = $row['a']
}

Upvotes: 0

Views: 9301

Answers (4)

Nikola
Nikola

Reputation: 11

I recently found myself facing this problem, and I believe I have found the solution. I will go over the problem itself, and also the solution, trying to explain everything along the way.

The problem was that I didn't have a two-dimensional array, but an array which could have any number of arrays inside arrays, so the solution by Brad F Jacobs couldn't apply here, although it's very simple and functional.

I had to work with a self-referencing database table called 'webpage', where one of the columns was 'parentWebpageId', which referenced an Id of some other row in that same table. This way, a tree structure can be built and easily managed, if you get your loops right.

Ia easily made a function which is supposed to generate a multi-dimensional array from one-dimensional self-referencing array, but the problem arose when I tried to make a function which should to the opposite. I needed this because if I wanted to delete a certain webpage, all it's children should also be deleted, in order to preserve the self-referential integrity.

It was easy to generate a tree whose root was the page that was initially to be deleted, but then I needed a list of all child webpage's Ids, in order to delete all of them.

So, the structure I had was something like this:

webpage1
    id
    title
    ...
    childWebpageArray
webpage2
    id
    title
    ...
    childWebpageArray
        webpage2.1
            id
            url
            ...
            childWebpageArray
        webpage2.2
            id
            url
            ...
            childWebpageArray
                webpage2.2.1
                    id
                    url
                    ...
                    childWebpageArray
                webpage2.2.2
                    id
                    url
                    ...
                    childWebpageArray
        webpage2.3
            id
            url
            ...
            childWebpageArray
webpage3
    id
    title
    ...
    childWebpageArray

As you can see, the depth can go forever.

What I came up with is this:

function flattenMultidimensionalArray($multidimensionalArray) {

    // Set anchor.
    ohBoyHereWeGoAgain:

    // Loop through the array.
    foreach ($multidimensionalArray as $key1 => $value1) {

        // Check if the webpage has child webpages.
        if (isset($multidimensionalArray[$key1]["childWebpageArray"]) && (count($multidimensionalArray[$key1]["childWebpageArray"]) > 0)) {

            // If it does, loop through all the child webpages, and move them into the initial multi-dimensional array.
            foreach ($multidimensionalArray[$key1]["childWebpageArray"] as $key2 => $value2) {
                $multidimensionalArray[] = $multidimensionalArray[$key1]["childWebpageArray"][$key2];
            }

            // Unset element's child pages, because all those child pages, along with their child pages
            // have been moved into the initial array, thus reducing the depth of a multi-dimensional array by 1.
            unset($multidimensionalArray[$key1]["childWebpageArray"]);
        }
    }

    // Loop once again through the whole initial array, in order to check if any of the pages has children
    foreach ($multidimensionalArray as $key => $value) {

        // If a page which has children is found, kick the script back to the beginning, and go through it again.
        if (isset($multidimensionalArray[$key]["childWebpageArray"]) && (count($multidimensionalArray[$key]["childWebpageArray"]) > 0)) {
            goto ohBoyHereWeGoAgain;
        }
    }

    // In the end, when there are no more pages with children, return an array of pages.
    return $multidimensionalArray;

}

This solution worked in my case, and I believe is the right one for this kind of problem. It probably isn't much of a hassle to change it in order to fit your particular needs.

Hope this helps!

Upvotes: 0

Md. Maruf Hossain
Md. Maruf Hossain

Reputation: 922

You Can Try As Like Following ......

    $multi_array = array(0 => array('a' => 5), 1 => array('a' => 8));
    $new_array = array();

    foreach ($multi_array AS $key => $value) {
        $new_array[] = $value['a'];
    }

Upvotes: 0

user1105633
user1105633

Reputation: 41

without foreach:

$array = array(0 => array('a' => 1), 1 => array('a' => 8));

$new_array = array_reduce($array, function ($result, $current) {$result[]=current($current); return $result;}, array());

Upvotes: 4

Jim
Jim

Reputation: 18853

If that is all your requirements are, I think that is the best way. Anything else will have the same processing. Even after looking through the Array functions, I would say that this would be the best way. You can, however, make it a function to make it a bit more versatile:

$array = array(0 => array('a' => 1), 1 => array('a' => 8));

$new_array = flatten($array, 'a');    

function flatten($array, $index='a') {
     $return = array();

     if (is_array($array)) {
        foreach ($array as $row) {
             $return[] = $row[$index];
        }
     }

     return $return;
}

But yea, I would say what you have would be the most efficient way of doing it.

Upvotes: 2

Related Questions