开发者

Better data structure or algorithm than iterative searching on multidimensional arrays to find corresponding values?

开发者 https://www.devze.com 2023-04-10 03:08 出处:网络
For a site I am working on I use a library to get a list of states.It returns a numerically indexed array of states, each with three keys: stateCode, stateName, and stateSeg. It looks like this:

For a site I am working on I use a library to get a list of states. It returns a numerically indexed array of states, each with three keys: stateCode, stateName, and stateSeg. It looks like this:

array
  0 => &
    array
      'stateCode' => string 'AL' (length=2)
      'stateName' => string 'Alabama' (length=7)
      'stateSeg' => string 'alabama-al' (length=10)
  1 => &
    array
     'stateCode' => string 'AK' (length=2)
      'stateName' => string 'Alaska' (length=6)
      'stateSeg' => string 'alaska-ak' (length=9)
  2 => &
    array
      'stateCode' => string 'AZ' (length=2)
      'stateName' => string 'Arizona' (length=7)
      'stateSeg' => string 'arizona-az' (length=10)

I often find myself with one of the three values and needing to look up its corresponding value. To do this I find myself constantly having to iterate through the array of states to find the data I need. Like this:

foreach ($this->data['stateList'] as $state)
{
    if ($state['stateCode'] == $searchParams['state'])
    {
        $stateSeg = $state['stateSeg'];
        break;
    }
}
$url = BASEURL . '/' . $stateSeg . ".html";

This seems inefficient to me. I think the most efficient solution I’ve been able to come up with is to turn开发者_Python百科 states into objects and put them in array with multiple keys for stateCode, stateSeg, and stateName each pointing to the same state object, so they can be referenced like this:

stateList[‘CA’]->getStateSeg();

or

stateList[‘Arizona’]->getStateCode();

or

stateList[‘alaska-ak’]->getStateName();

etc…

This also seems like kind of a hack which would result in a rather large array (150 keys pointing to 50 objects) with replicated data (keys replicating data stored within objects).

Anyway, just thought I’d see if there is some kind of pattern for this type of problem. This array of states isn't the only thing I’ve come across where I’ve had to do this sort of iterative searching on multidimensional arrays to find corresponding values.

Question is tagged PHP and the code above is in PHP, but I am interested in elegant solutions in any language.


If php supports references and I know the state, I'd just pass a reference to the appropriate array element and extract from it the necessary field.

Alternatively, if you never know in advance what state you can get, create and use a map (associative container/array), let its efficient implementation take care of quickly finding whatever you need. Seems like you may need several of them.

Also, I wonder if you could get rid of everything except the "alaska-ak" strings. The data appears highly redundant.


I think your basic idea with the object and the arrays is not that bad, but instead of creating actually objects, I would just refer to the existing objects (better: array data). Let's see your original list again:

array
  0 => &
    array
      'stateCode' => string 'AL' (length=2)
      'stateName' => string 'Alabama' (length=7)
      'stateSeg' => string 'alabama-al' (length=10)
  1 => &
    array
     'stateCode' => string 'AK' (length=2)
      'stateName' => string 'Alaska' (length=6)
      'stateSeg' => string 'alaska-ak' (length=9)
  2 => &
...

Each state object has an identifier, the array key: 0, 1, 2, ... .

All you need to do is to create three indexes based on key. You use the value as key (e.g. "AL" for "stateCode" index) and as value you take the array index, 0:

$indexStateCode['AL'] = 0;

You can then already look this up quickly:

$states[$indexStateCode['AL']];

Encapsulate this into a class with ArrayAccess and then on request instantiate the state object. You don't need it earlier.


Could you store the states in a mysql/sqlite table and use the database engine to do the lookup?


This seems inefficient to me

It isn't. Even worse-case, iterating through 50 items is probably an order of magnitude faster than querying a db.

a library to get a list of states

Not sure why you'd need a library to do this. But I'd either change the library to return the array how you need it, or wrap it in another module.

The data is somewhat redundant... All you need is two items: the state code and the state name. You can construct the "state seg" from those two. So keep a state code map and a state name map.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号