比多维数组上的迭代搜索更好的数据结构或算法来查找相应的值?
对于我正在使用的网站,我使用库来获取状态列表。它返回一个数字索引的状态数组,每个状态都有三个键: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中,但我感兴趣的是在任何语言优雅的解决方案。
如果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”。所以保持一个状态代码映射和一个状态名称映射。
虽然线性搜索并不是特别有效,但在这样一个小桌子上应该足够快,这取决于你打电话的频率。如果你每秒没有触及数百次,那么你会浪费你的时间来优化它。 –
如果你想优化这个,那么你需要交换一些东西来获得别的东西。线性搜索的内存效率很高,但速度很慢。你建议的另一个解决方案,有3个键指向相同的对象是一个很好的解决方案,但你交易一些内存,以减少获得所需数据的步骤数。所以是的,你会创建3个数组,每个指向一个对象。 – Furicane
使用一些DBMS .... – gd1