Mike
Mike

Reputation: 169

Change keys in each row of a 2d array without losing values

I have an array of rows where one (visual) column of data has two similar but different keys. I would like to replace one of the keys so that the column has the same key in all rows.

My input array:

[
    ['Ttitle' => 'lilly', 'Price' => 1.75, 'Number' => 3],
    ['Title' => 'rose',   'Price' => 1.25, 'Number' => 15],
    ['Title' => 'daisy',  'Price' => 0.75, 'Number' => 25],
    ['Title' => 'nettle', 'Price' => 2.75, 'Number' => 33],
    ['Title' => 'orchid', 'Price' => 1.15, 'Number' => 7],
];

My desired result: (notice the key change for lilly)

[
    ['Title' => 'lilly',  'Price' => 1.75, 'Number' => 3],
    ['Title' => 'rose',   'Price' => 1.25, 'Number' => 15],
    ['Title' => 'daisy',  'Price' => 0.75, 'Number' => 25],
    ['Title' => 'nettle', 'Price' => 2.75, 'Number' => 33],
    ['Title' => 'orchid', 'Price' => 1.15, 'Number' => 7],
];

When I attempted to use array_map(), I manage to change all the keys to Title, but I also delete all Title values except for the Ttitle key I just changed to Title.

Code is as follows:

if (!empty($notmatchingarray))
{
    $completearray = array_merge($notmatchingarray, $datastuff2);

    $completearray = array_map(
        function($complete) {
            return array(
                'Title' => $complete['Ttitle'],
                'Price' => $complete['Price'],
                'Number' => $complete['Number'],
            );
        },
        $completearray
    );
    print_r($completearray);
}

Am I doing the wrong thing in using this array_map() function? Should I be doing something else?

Upvotes: 2

Views: 3591

Answers (3)

mickmackusa
mickmackusa

Reputation: 47874

Your rows of data are statically positioned, so honestly, you can just use iterated calls of array_combine() with your preferred keys.

If your row elements are not predictably positioned, then you can simplify/modernize the earlier posted answers with the null coalescing operator.

Codes: (Demo)

var_export(
    array_map(
        fn($row) => array_combine(['Title', 'Price', 'Number'], $row),
        $array
    )
);

Or:

var_export(
    array_map(
        fn($row) => ['Title' => $row['Ttitle'] ?? $row['Title'], 'Price' => $row['Price'], 'Number' => $row['Number']],
        $array
    )
);

Upvotes: 0

AbraCadaver
AbraCadaver

Reputation: 78994

Better ways but I'm headed out. With your existing code you need to set Ttitle or Title whichever is present:

$completearray = array_map(function($complete) {
        $title = isset($complete['Ttitle']) ? $complete['Ttitle'] : $complete['Title'];
        return array(
           'Title' => $title,
           'Price' => $complete['Price'],
           'Number' => $complete['Number'],
       );
}, $completearray);

Ternary operator is a shortcut for a simple if / else, so:

if(isset($complete['Ttitle'])) {
    $title = $complete['Ttitle']; //if Ttitle is set use it
} else {
    $title = $complete['Title'];  //if not use Title
}

Upvotes: 3

p.s.w.g
p.s.w.g

Reputation: 149000

You might try using the array_key_exists function:

$completearray = array_map(function($complete) {
    return array(
       'Title' => (array_key_exists('Title', $complete) 
                   ? $complete['Title'] 
                   : $complete['Ttitle']),
       'Price' => $complete['Price'],
       'Number' => $complete['Number'],
   );
}, $completearray);

Or if you prefer:

$completearray = array_map(function($complete) {
    $titleKey = array_key_exists('Title', $complete) ? 'Title' : 'Ttitle';
    return array(
       'Title' => $complete[$titleKey],
       'Price' => $complete['Price'],
       'Number' => $complete['Number'],
   );
}, $completearray);

If the array $complete contains the key, 'Title', it will use that; otherwise it will use the key 'Ttitle'.

Upvotes: 2

Related Questions