2011-09-29 94 views
1

對於我正在使用的網站,我使用庫來獲取狀態列表。它返回一個數字索引的狀態數組,每個狀態都有三個鍵: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

回答

0

你能保存狀態在MySQL/SQLite表和使用數據庫引擎進行查找?

+0

不,我從庫中得到上述狀態數組。 – joecan

+3

你基本上使用這個庫,就像它是一個內存數據庫一樣。您的查找數組是索引。爲什麼不使用數據庫並在更新庫時保持最新?或者將你的索引添加到上述庫中。無論哪種方式,你都有一個數據庫,其索引需要變得高效。 – enobrev

1

如果PHP支持引用和我知道的狀態下,我只是傳遞給適當的數組元素的引用,並從中提取必要的字段。

或者,如果你永遠不知道事先什麼狀態,你可以得到,創建和使用地圖(關聯容器/陣列),讓其有效的實施採取快速查找你需要的任何服務。似乎你可能需要其中的幾個。

另外,我不知道你是否能擺脫一切的除了「阿拉斯加-AK」的字符串。數據顯得非常多餘。

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類然後根據請求實例化狀態對象。你以前不需要它。

0

這似乎效率不高我

它不是。更糟糕的是,迭代50個項目可能比查詢數據庫快一個數量級。

庫獲得國家

不知道名單爲什麼你需要一個庫來做到這一點。但是我會改變庫來返回你需要的數組,或者將它包裝在另一個模塊中。

數據有點多餘...您只需要兩項:狀態碼和狀態名稱。你可以從這兩個構造「狀態seg」。所以保持一個狀態代碼映射和一個狀態名稱映射。