2

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?

mickmackusa
  • 43,625
  • 12
  • 83
  • 136
Mike
  • 169
  • 2
  • 12

3 Answers3

3

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
}
AbraCadaver
  • 78,200
  • 7
  • 66
  • 87
  • Thanks again for your help, works straight away. Does that $title variable basically say if the Key in $complete is Ttitle then swap $complete['Ttitle'] with $complete['Title']. And if i had all the keys with different names but similar values could i then use the same principle to change all the keys? – Mike Mar 12 '14 at 21:48
  • @Mike No, it doesn't swap the values. `?:` is the [ternary operator](http://php.net/manual/en/language.operators.comparison.php#language.operators.comparison.ternary) (also called the conditional operator). It's basically a compact version of an if/else statement. – p.s.w.g Mar 12 '14 at 22:02
2

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'.

p.s.w.g
  • 146,324
  • 30
  • 291
  • 331
  • @Mike What about it didn't work? Did you get an error? I had a problem in my initial answer (`in_array` instead of `array_key_exists`), but I have since corrected it. Please see my updated answer. – p.s.w.g Mar 12 '14 at 21:44
  • Ah it works now i must of jumped the gun. Great help thank you! Could i in theory expand on this to change all keys to a particular name if the multidimensional array had a lot more different keynames.? – Mike Mar 12 '14 at 21:55
  • @Mike Sure. You could tweak the second example pretty easily. You could even create an array of keys and just pick the first one that was found. whichever way you want to do it, Find the correct key and assign it to `$titleKey`. Your return statement would stay the same. – p.s.w.g Mar 12 '14 at 21:59
0

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
    )
);
mickmackusa
  • 43,625
  • 12
  • 83
  • 136