Stenerson
Stenerson

Reputation: 1002

How to replace id values in array with their actual values stored in another array?

I have two associative arrays, one with data about states (or provinces) and one with different countries. I'm getting the values from a relational database so the states array doesn't hold the country name but rather the country id.

States Array:

array(3) {
  array {
    'name' => 'Alabama',
    'country' => 1},
  array {
    'name' => 'Alberta',
    'country' => 2},
  array {
    'name' => 'Minnesota',
    'country' => 1}
}

Countries Array:

array(2) {
    1 => 'United States',
    2 => 'Canada'
}

The result I want is:

array(3) {
  array {
    'name' => 'Alabama',
    'country' => 'United States'},
  array {
    'name' => 'Alberta',
    'country' => 'Canada'},
  array {
    'name' => 'Minnesota',
    'country' => 'United States'}
}

I searched and searched and haven't found a question that answers this specific problem. I'm sure I'm not the only one who has data like this; maybe I'm not looking for the right terms. I did write a function in my Country model class to solve this but I'm thinking there has to be a more efficient way.


My current solution (it works but there's probably a better way, right?):

function replaceKeyValues($replaceArray,$replaceKey)
  {
  $countries = $this->get_countries();
  foreach ($replaceArray as &$itm) {
    if (isset($itm[$replaceKey])) {
      if (in_array($itm[$replaceKey], array_flip($countries))) {
        $itm[$replaceKey] = $countries[$itm[$replaceKey]];
      }
    }
  }
  return $replaceArray;
}

//called like this (for example)
$states = $this->Country->replaceKeyValues($states,'country');

Edit: I ended up using Jon's suggestion and also slightly modified the original function to make it generic enough that I don't need it in my model class anymore. It's now in one of my helper classes, and I added another input parameter which is the "master data" array. Hopefully this helps someone :-)

function replaceKeyValues($masterArray,$replaceArray,$replaceKey)
{
    foreach ($replaceArray as &$itm) {
        if (isset($itm[$replaceKey])) {
            if (isset($masterArray[$itm[$replaceKey]])) {
                $itm[$replaceKey] = $masterArray[$itm[$replaceKey]];
            }
        }
    }
    return $replaceArray;
}

Upvotes: 2

Views: 118

Answers (1)

Jon
Jon

Reputation: 437534

Apart from the fact that this

if (in_array($itm[$replaceKey], array_flip($countries)))

would be much better written as

if (isset($countries[$itm[$replaceKey]]))

and the fact that the nested conditions can be de-nested, this is basic enough that there's no real opportunity for improvement.

You could of course replace the foreach with array_walk and a lambda, but that wouldn't be any "better".

Upvotes: 4

Related Questions