比在多维数组上迭代搜索找到相应值更好的数据结构或算法


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

对于我正在工作的一个站点,我使用库来获取状态列表。它返回一个数字索引的状态数组,每个状态都有三个键:stateCode、stateName和stateSeg。它看起来像这样:

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)

我经常发现自己有三个值中的一个,需要查找其对应的值。为了做到这一点,我发现自己必须不断地遍历状态数组来找到我需要的数据。这样的:

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

这对我来说似乎效率低下。我认为我能想出的最有效的解决方案是将状态转换为对象,并将它们放入数组中,其中包含stateCode, stateSeg和stateName的多个键,每个键都指向相同的状态对象,因此它们可以像这样引用:

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

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

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

等等……

这看起来也像是一种hack,它会导致一个相当大的数组(150个键指向50个对象)与复制数据(键复制存储在对象中的数据)。

不管怎样,我只是想看看这类问题是否有某种模式。这种状态数组并不是我遇到的唯一一种必须在多维数组上进行这种迭代搜索以找到相应值的情况。

问题被标记为PHP,上面的代码是在PHP中,但我对中的优雅解决方案感兴趣任何语言

如果php支持引用,我知道状态,我只需要传递一个引用到适当的数组元素,并从中提取必要的字段。

或者,如果你事先不知道你可以得到什么状态,创建和使用映射(关联容器/数组),让它的高效实现来快速找到你需要的任何东西。看来你可能需要几个。

另外,我想知道您是否可以删除除"alaska-ak"字符串之外的所有内容。数据显得高度冗余。

我认为你的基本想法与对象和数组不是那么糟糕,但不是创建实际对象,我只是指现有的对象(更好的:数组数据)。让我们再看一遍你的原始列表:

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 => &
...

每个状态对象都有一个标识符,数组键:0,1,2,... .

您所需要做的就是基于key创建三个索引。您使用值作为键(例如:"AL"表示"stateCode"索引),作为数组索引的值,0:

$indexStateCode['AL'] = 0;

你已经可以快速查找了:

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

用ArrayAccess将其封装到一个类中,然后在请求时实例化状态对象。

您可以将状态存储在mysql/sqlite表中并使用数据库引擎进行查找吗?

这对我来说似乎效率低下

它不是。更糟糕的情况是,遍历50个条目可能比查询数据库快一个数量级。

获取状态列表的库

不知道为什么你需要一个库来做这个。但是我要么更改库以返回您需要的数组,要么将其包装在另一个模块中。

数据有些冗余……您只需要两个项目:州代码和州名。您可以从这两个构造"状态段"。所以保留一个州代码地图和一个州名地图