Viewed   64 times

Possible Duplicate:
PHP convert nested array to single array while concatenating keys?
Get array's key recursively and create underscore seperated string

Please, read the whole question before answering.

I have this multidimensional array:

$data = array(
    'user' => array(
        'email'   => 'user@example.com',
        'name'    => 'Super User',
        'address' => array(
            'billing' => 'Street 1',
            'delivery' => 'Street 2'
        )
    ),
    'post' => 'Hello, World!'
);

I want it flatten, transformed into:

$data = array(
    'user.email' => 'user@example.com',
    'user.name'  => 'Super User',
    'user.address.billing'  => 'Street 1',
    'user.address.delivery' => 'Street 2',
    'post'       => 'Hello, World!'
);

Important:

  • The keys are very important to me. I want them concatenated, separated by periods.

  • It should work with any level of nesting.

Thank you!

 Answers

5

Thanks for all the given answers.

I have transformed it in the following, which is an improved version. It eliminates the need of a root prefix, does not need to use references, it is cleaner to read, and it has a better name:

function array_flat($array, $prefix = '')
{
    $result = array();

    foreach ($array as $key => $value)
    {
        $new_key = $prefix . (empty($prefix) ? '' : '.') . $key;

        if (is_array($value))
        {
            $result = array_merge($result, array_flat($value, $new_key));
        }
        else
        {
            $result[$new_key] = $value;
        }
    }

    return $result;
}
Friday, December 23, 2022
4

You need to iterate over your results, adding a new entry to the output when you encounter a new team, or updating the points value when you find the same team again. This is most easily done by initially indexing the output by the team name, and then using array_values to re-index the array numerically:

$teams = array();
foreach ($results as $result) {
    $team = $result['team'];
    if (!isset($teams[$team])) {
        $teams[$team] = array('team' => $team, 'points' => $result['punti']);
    }
    else {
        $teams[$team]['points'] += $result['punti'];
    }
}
$teams = array_values($teams);
print_r($teams);

Output (for your sample data):

Array
(
    [0] => Array
        (
            [team] => Red Bull Racing
            [points] => 418
        )
    [1] => Array
        (
            [team] => Scuderia Ferrari
            [points] => 353
        )
    [2] => Array
        (
            [team] => Mercedes-AMG
            [points] => 516
        )
    [3] => Array
        (
            [team] => Racing Point F1
            [points] => 147
        )
    [4] => Array
        (
            [team] => Haas F1
            [points] => 127
        )
)

Demo on 3v4l.org

Friday, August 12, 2022
 
1

Simply set it while looping:

$alttitle = "35:title1,36:title2, 59:title5"
$tmptitles = explode(",",$alttitle);

$replacetitle = array();
foreach($tmptitles as $tmptitle) {
   $tmparr = explode(":", trim($tmptitle));
   $replacetitle[intval($tmparr[0])] = trim($tmparr[1]);
}

With the above, you will create your array a minimum number of iterations.

Thursday, October 13, 2022
3

You can do it like this, do the calculation from the innermost of the array. Check the demo.

<?php
function f(&$array)
{
    foreach($array as $k => &$v)
    {
        if(is_array($v))
        {
            if(count($v) == count($v, 1))
            {
                unset($array[$k]);
                if($k == 'sum')
                {
                    $v =  array_sum($v);
                    $array[] = $v;

                }elseif($k == 'multiply'){
                    $v = array_product($v);
                    $array[] = $v;
                }else{

                    foreach($v as $vv)
                        $array[] = $vv;
                }
            }else
                f($v);
        }
    }
}

while(count($array) != count($array, 1))
{
    f($array);
}

print_r($array);

Note:

traverse array from outer to inner
traverse array from inner to outer

Monday, November 14, 2022
 
4

Do the recursive flattening from the inside out. First call the flatten function on the array that you find, then move the contents of that (now flat) array into the parent array. Loop backwards through the array so that you don't have to adjust the loop variable for the items that are inserted.

As you know that the arrays that you insert are flat, you can use the splice method to replace an array with its items.

It works like this:

start with
[[[2, 3], 4], 5, [6, 7]]

flatten [6,7] (which is already flat) and insert:
[[[2, 3], 4], 5, 6, 7]

flatten [[2, 3], 4] recursively calls flatten [2,3] and inserts in that array:
[[2, 3, 4], 5, 6, 7]
then it inserts [2, 3, 4]:
[2, 3, 4, 5, 6, 7]

Code:

function flatten(arr) {
  for (var i = arr.length - 1; i >= 0; i--) {
    if (arr[i].constructor === Array) {
      flatten(arr[i]);
      Array.prototype.splice.apply(arr, [i, 1].concat(arr[i]));
    }
  }
}

var x = [[[2, 3], 4], 5, [6, 7]];

flatten(x);

// Show result in snippet
document.write(JSON.stringify(x));
Friday, September 9, 2022
 
kim_d.
 
Only authorized users can answer the search term. Please sign in first, or register a free account.
Not the answer you're looking for? Browse other questions tagged :