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

问题描述:

对于我正在使用的网站,我使用库来获取状态列表。它返回一个数字索引的状态数组,每个状态都有三个键: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中,但我感兴趣的是在任何语言优雅的解决方案。

+0

虽然线性搜索并不是特别有效,但在这样一个小桌子上应该足够快,这取决于你打电话的频率。如果你每秒没有触及数百次,那么你会浪费你的时间来优化它。 –

+0

如果你想优化这个,那么你需要交换一些东西来获得别的东西。线性搜索的内存效率很高,但速度很慢。你建议的另一个解决方案,有3个键指向相同的对象是一个很好的解决方案,但你交易一些内存,以减少获得所需数据的步骤数。所以是的,你会创建3个数组,每个指向一个对象。 – Furicane

+0

使用一些DBMS .... – gd1

你能保存状态在MySQL/SQLite表和使用数据库引擎进行查找?

+0

不,我从库中得到上述状态数组。 – joecan

+3

你基本上使用这个库,就像它是一个内存数据库一样。您的查找数组是索引。为什么不使用数据库并在更新库时保持最新?或者将你的索引添加到上述库中。无论哪种方式,你都有一个数据库,其索引需要变得高效。 – enobrev

如果PHP支持引用和我知道的状态下,我只是传递给适当的数组元素的引用,并从中提取必要的字段。

或者,如果你永远不知道事先什么状态,你可以得到,创建和使用地图(关联容器/阵列),让其有效的实施采取快速查找你需要的任何服务。似乎你可能需要其中的几个。

另外,我不知道你是否能摆脱一切的除了“阿拉斯加-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,...。

您只需要根据键创建三个索引。您使用该值作为关键字(例如,“AL”为“stateCode”指数)和价值,你把数组索引,0:

$indexStateCode['AL'] = 0; 

然后你可以已经快速查找这件事:

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

封装这个与ArrayAccess类然后根据请求实例化状态对象。你以前不需要它。

这似乎效率不高我

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

库获得国家

不知道名单为什么你需要一个库来做到这一点。但是我会改变库来返回你需要的数组,或者将它包装在另一个模块中。

数据有点多余...您只需要两项:状态码和状态名称。你可以从这两个构造“状态seg”。所以保持一个状态代码映射和一个状态名称映射。