2011-03-10 49 views
24

我有一個這樣的數組(剛剛超過3000個對象,而不是這裏的3):什麼是最好的方式來查詢JavaScript中的數組來獲取我想要的項目?

items = [{name:'charlie', age:'16'}, {name:'ben', age:'18'}, {name:'steve', age:'18'}] 

什麼是返回與人誰是18只是對象的數組的最佳方式?所以,我想:

items = [{name:'ben', age:'18'}, {name:'steve', age:'18'}] 

我能想到的最好的是這(使用jQuery):

newArray = [] 
$.each(items, function(index, item) { 
    if(item.age=='18') { 
     newArray.push(item) 
    } 
}) 

考慮到有300萬點的對象,而且也是我會做的是比較達一次去五十次,這是很多循環。有沒有更好的辦法?

+0

爲了進一步澄清,我從數據庫的初始頁面加載創建此數組。在整個體驗過程中都需要相同的信息,所以我認爲從這個數組訪問它可能會比每次調用數據庫都快。無論如何我都需要它,所以我猜這是有道理的。如果有更好的方法糾正我。 – 2011-03-10 10:15:29

+0

See below: http://stackoverflow.com/questions/777455/is-there-a-query-language-for-json – Brij 2011-03-10 09:41:51

+0

肯尼:你看@大衛的解決方案!!?!? – billy 2012-05-03 18:00:50

回答

45

您可以使用純JavaScript

var wanted = items.filter(function(item){return (item.age==18);}); 

如果你的瀏覽器不支持1.6版的JavaScript,您可以在https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/filter


發現過濾方法的實現更新

快速有個 巨大的 變化(取決於瀏覽器)(有在測試錯誤)差從正常回路..看一看這個小測試我在http://jsperf.com/array-filter-vs-loop/3

+0

這看起來相當簡單,我喜歡它,並且可以更多地使用它。只是圍繞一些其他的建議來看看是否有什麼更好的性能方面,我認爲這在後臺循環很多,但也許這不會是一個問題。 – 2011-03-10 10:10:19

+0

@Kenny Flannery:「缺點」是你爲每個項目調用一個函數。正常的'for'循環可能會更快。 – 2011-03-10 10:35:00

+0

不錯的測試鏈接,現在使用for循環。 – 2011-03-11 01:08:38

0

使用陣列的過濾器製造方法它會爲數組中的每個元素調用一次提供的回調函數。

array.filter(<callbackfucntion>[, <Object to use>]) 
+0

你不得不提到,這是ES5中引入的方法,可能在所有瀏覽器(特別是舊版本)中都不可用。 – 2011-03-10 09:52:18

+1

啊學到了新東西!不知道。謝謝@Felix – CloudyMarble 2011-03-10 10:09:16

4

無論您選擇哪種方法(item.filter或任何用於json的「查詢語言」),for循環都是不可避免的。

如果性能是一個問題,我會建議您使用純JavaScript而不是類似jQuery的庫,這會增加整個處理的開銷,這是明顯的here

因此,你的代碼看起來像:

var newArray = []; 
for(var i=0;i<items.length;i++) { 
    var item = items[i]; 
    if(item.age == '18') { 
     newArray.push(item); 
    } 
}); 
5

如果你打算做搜索往往也可能是最好保持一個版本的數據的一種形式,它是快速訪問。 我已經使用underscore.js(http://documentcloud.github.com/underscore/)來讓自己更容易,但是這裏的代碼將創建一個對象,該對象保存由age字段索引的數據。

你最終的東西,看起來像這樣:

{ 
    "16": [ 
     { 
      "name": "charlie", 
      "age": "16" 
     } 
    ], 
    "18": [ 
     { 
      "name": "ben", 
      "age": "18" 
     }, 
     { 
      "name": "steve", 
      "age": "18" 
     } 
    ] 
} 

代碼:

var itemsByAge = _(items).reduce(function(memo, item) { 
    memo[item.age] = memo[item.age] || []; 
    memo[item.age].push(item); 
    return memo; 
}, {}); 

alert(JSON.stringify(itemsByAge["18"])); 
+0

不錯!在閱讀這個問題時,我正在考慮這樣的事情! – billy 2012-05-03 17:58:12

0

一次我有這樣的問題,我解決它像這樣 1-創建數組的數組012-2-每個索引創建索引記錄 例如

var pAry=[]; 
var cAry=[{name:'ben', age:'18'}, {name:'steve', age:'18'}] 
pAry[17]=cAry; 

當u需要的人與18歲這樣,您將獲得指數17

+0

這與我所解決的問題很接近,除了所有的關聯數組或對象外。 – 2011-03-12 04:09:09

2

利用JavaScript的宏偉功能eval()的,其評價串在運行時代碼,我們可以定義爲一個原型法陣列型

Array.prototype.where = function (query) { 
var newArray = []; 
for(var i=0; i<this.length; i++) { 
    var item = this[i]; 
    if(eval("item" + query)) { 
     newArray.push(item); 
    } 
} 
return newArray; 
}; 

,並與任何陣列使用它,通過作爲查詢字符串

var newArray= items.where('.age >= 18'); 
相關問題