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

时间:2011-09-29 22:01:15

标签: php arrays algorithm oop data-structures

对于我正在处理的网站,我使用库来获取状态列表。它返回一个数字索引的状态数组,每个状态都有三个键: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();

等...

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

无论如何,只是想到我会看到这类问题是否存在某种模式。这个状态数组并不是我遇到的唯一一个我必须在多维数组上进行这种迭代搜索以找到相应值的地方。

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

4 个答案:

答案 0 :(得分:1)

如果php支持引用并且我知道状态,我只是传递对相应数组元素的引用并从中提取必要的字段。

或者,如果您事先不知道可以获得什么状态,请创建并使用地图(关联容器/数组),让其高效实施可以快速找到您需要的任何内容。好像你可能需要其中几个。

另外,我想知道你是否可以摆脱除“阿拉斯加 - 阿克”字符串之外的所有东西。数据显得多余。

答案 1 :(得分:0)

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

答案 2 :(得分:0)

我认为你对象和数组的基本思想并不是那么糟糕,但我不是创建实际的对象,而是引用现有的对象(更好的是:数组数据)。让我们再次看到您的原始列表:

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,...。

您需要做的就是基于密钥创建三个索引。您使用值作为键(例如“AL”表示“stateCode”索引),并将值作为数组索引,0:

$indexStateCode['AL'] = 0;

然后你可以快速查看:

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

将此封装到具有ArrayAccess的类中,然后在请求时实例化状态对象。你不需要它。

答案 3 :(得分:0)

  

这对我来说效率低下

不是。更糟糕的情况是,迭代50个项目可能比查询数据库快一个数量级。

  

获取状态列表的库

不确定为什么你需要一个库才能这样做。但是我要么改变库以返回数组你需要它,要么将它包装在另一个模块中。

数据有些多余......您只需要两个项目:州代码和州名称。你可以从这两个构建“状态段”。因此,请保留州代码映射和州名称映射。