1

I would like to replace keys in arrays, because I will move them on two indexes up. Problem that I am facing is that those are containing same names which will not be ok, if i want to move them up.

This is how array looks like.

$list = array(
'ind' => array(
    'messagetype' => 'Alert',
    'visibility' => 'Public',
    'info' => array(
        0 => array(
            'urgency' => 'Urgent',
            'params' => array(
                0 => array(
                    'Name' => 'display',
                    'value' => '3; top',
                ),
                1 => array(
                    'Name' => 'level',
                    'value' => '1; blue',
                ),
            ),
            'area' => array(
                'ard' => 'Bob',
                'code' => array(
                    0 => array(
                        'Name' => 'Badge',
                        'value' => 'GSSD154',
                    ),
                ),
            ),
        ),
        1 => array(
            'messagetype' => 'Information',
            'visibility' => 'Private',
            'info' => array(
                0 => array(
                    'urgency' => 'Minor',
                    'params' => array(
                        0 => array(
                            'Name' => 'display',
                            'value' => '1; left',
                        ),
                        1 => array(
                            'Name' => 'level',
                            'value' => '1; red',
                        ),
                    ),
                    'area' => array(
                        'ard' => 'Bob',
                        'code' => array(
                            0 => array(
                                'Name' => 'Badge',
                                'value' => 'GBECS23',
                            ),
                        ),
                    ),
                ),
            ),
        ),
    ),
),

);

and this is how I would like the output to be with changing keys in Name0, Name1, which are inside params.

$list = array(
'ind' => array(
    'messagetype' => 'Alert',
    'visibility' => 'Public',
    'info' => array(
        0 => array(
            'urgency' => 'Urgent',
            'params' => array(
                0 => array(
                    'Name0' => 'display',
                    'value0' => '3; top',
                ),
                1 => array(
                    'Name1' => 'level',
                    'value1' => '1; blue',
                ),
            ),
            'area' => array(
                'ard' => 'Bob',
                'code' => array(
                    0 => array(
                        'Name' => 'Badge',
                        'value' => 'GSSD154',
                    ),
                ),
            ),
        ),
        1 => array(
            'messagetype' => 'Information',
            'visibility' => 'Private',
            'info' => array(
                0 => array(
                    'urgency' => 'Minor',
                    'params' => array(
                        0 => array(
                            'Name0' => 'display',
                            'value0' => '1; left',
                        ),
                        1 => array(
                            'Name1' => 'level',
                            'value1' => '1; red',
                        ),
                    ),
                    'area' => array(
                        'ard' => 'Bob',
                        'code' => array(
                            0 => array(
                                'Name' => 'Badge',
                                'value' => 'GBECS23',
                            ),
                        ),
                    ),
                ),
            ),
        ),
    ),
),

);

I have tried with a lots of examples over this website, but could not find one to achieve this. Code that I used from How to replace key in multidimensional array and maintain order

       function replaceKey($subject, $newKey, $oldKey) {

    // if the value is not an array, then you have reached the deepest
    // point of the branch, so return the value
    if (!is_array($subject)) {
        return $subject;
    }

    $newArray = array(); // empty array to hold copy of subject
    foreach ($subject as $key => $value) {

        // replace the key with the new key only if it is the old key
        $key = ($key === $oldKey) ? $newKey : $key;

        // add the value with the recursive call
        $newArray[$key] = replaceKey($value, $newKey, $oldKey);
    }
    return $newArray;
}
$s = replaceKey($list, 'Name0', 'Name');

print "<PRE>";

print_r($s);

at the moment I get this output:

                                                [0] => Array
                                                    (
                                                        [Name0] => display
                                                        [value] => 1; left
                                                    )
                                                [1] => Array
                                                    (
                                                        [Name0] => level
                                                        [value] => 1; red
                                                    )

any help would be appreciated. regards

Romanoffa
  • 71
  • 2
  • 9
  • Well, you can't use that function from the other question because you need to rename the same index ("Name") to different values and only when under a certain key ("params"), but ignore other. That function is general and your algorithm is specific. But why are you renaming this afterwards? Do you not have access to the code that generates the array? Correcting the generating algorithm seems like the more logical option. – El_Vanja Mar 28 '20 at 17:13
  • hi, array is pulled from other website and converted from json. – Romanoffa Mar 28 '20 at 17:28
  • 1
    Can you simply concatenate the key of the containing array (0, 1...) onto the name and value keys when you're reading them? Seems like this complex operation could be avoided. – El_Vanja Mar 28 '20 at 17:32
  • I have tried already with adding ['0'] and ['1'] to access it, but it is not dynamic. hmhh maybe the best solution would be to convert array from multidimensional to twodimensional maybe, but i will still need a renaming. – Romanoffa Mar 28 '20 at 17:40
  • 1
    What I'm trying to say is that you are surely using this array somewhere later on (reading from it). When reading, you have to iterate it. In that iteration you have both the current key of containing array (0, 1...) and the current key of your parameter (name, value). If you really need a combined key, you can create it there. Seems like an overkill to iterate once to change keys and then iterate again to read it. – El_Vanja Mar 28 '20 at 17:48

1 Answers1

1

A very strange question, but why not?

The following function returns nothing (a procedure) and changes the array in-place using references but feel free to rewrite it as a "real" function (without references and with a return statement somewhere).

The idea consists to search for arrays, with numeric keys and at least 2 items, in which each item has the Name and value keys. In other words, this approach doesn't care about paths where the targets are supposed to be:

function replaceKeys(&$arr) {

    foreach ($arr as &$v) {
        if ( !is_array($v) )
            continue;

        $keys = array_keys($v);

        if ( count($keys) < 2 ||
             $keys !== array_flip($keys) ||
             array_keys(array_merge(...$v)) !== ['Name', 'value'] ) {
            replaceKeys($v);
            continue;
        }

        foreach ($v as $k => &$item) {
            $item = array_combine(["Name$k", "value$k"], $item);
        }
    }
}

replaceKeys($list);
print_r($list);

demo

Casimir et Hippolyte
  • 88,009
  • 5
  • 94
  • 125