2016-03-01 58 views
0

在JavaScript中,我需要一個有效的方式,它具有以下形式的數組訪問文檔:通過文檔內部數組中的鍵訪問文檔的有效方法?

[ 
    { 
     a : '1', 
     b : '2', 
     c : '3' 
    }, 
    { 
     a : '4', 
     b : '5', 
     c : '6' 
    }, 
    {...}, 
    {...} 
] 

所以,所有的文件具有相同的密鑰。如果我的值爲a(例如a = 4),是否有辦法從數組中檢索文檔,其中a = 4沒有循環遍歷數組中的所有元素並執行檢查?

+0

你這是什麼意思是_documents_? – Rayon

+0

根據我的理解,文檔是數組中的一個對象 –

回答

4

只有您顯示的數據結構,沒有任何方法可以檢索到對象,其中a是=== '4'而沒有在數組中循環的某些代碼。數組沒有任何權力來查找其中的嵌套對象中的內容而無需循環。

這將有可能構建陣列的單獨的索引或將數據重組爲一個不同類型的數據結構,然後,將允許您無需循環檢索所需的項目,但不作爲已構成有數據。例如,您可以在數組上循環一次,然後構建數組中存在的所有a值的索引,以便通過該索引的一次訪問,可以知道哪些數組元素包含所需的值a。但是,在使用它之前,您必須首先構建該類型的索引。如果這是一次訪問,那不會爲您節省任何時間,但是如果您要一遍又一遍地查找a的值,則可以節省大量時間。建立索引一次,然後多次使用它來提高查找特定值的效率。


爲了查找數據的更有效的方法,如果陣列是大的,這裏是爲後,一旦索引數據,然後使用該索引多次的方案。這是假定該數據是一個字符串或具有無歧義字符串轉換(其中你的例子適合):

var data = [ 
 
    { a : '1', b : '2', c : '3', d : '1'}, 
 
    { a : '4', b : '5', c : '6', d : '1'}, 
 
    { e : '3', a : '1', c : '5'}, 
 
]; 
 

 
function ArrayIndex(data) { 
 
    var index = {}; 
 
    data.forEach(function(obj, i) { 
 
     Object.keys(obj).forEach(function(key) { 
 
      var combinedKeyVal = "_" + key + "_" + obj[key]; 
 
      var slot = index[combinedKeyVal]; 
 
      if (!slot) { 
 
       slot = index[combinedKeyVal] = []; 
 
      } 
 
      // add this index to the slot array 
 
      slot.push(i) 
 
     }); 
 
    }); 
 
    
 
    this.find = function(key, val) { 
 
     var combinedKeyVal = "_" + key + "_" + val; 
 
     return index[combinedKeyVal] || []; 
 
    } 
 
} 
 

 
var index = new ArrayIndex(data); 
 
var found = index.find('a', '4'); 
 
log(found); 
 
found = index.find('d', '1'); 
 
log(found); 
 
found = index.find('c', '5'); 
 
log(found); 
 
found = index.find('d', '2'); 
 
log(found); 
 

 
// display output in snippet 
 
function log(x) { 
 
    var div = document.createElement("div"); 
 
    div.innerHTML = JSON.stringify(x); 
 
    document.body.appendChild(div); 
 
}

+0

非常感謝。在這個階段,似乎我只會訪問一次數組,所以我想我只需要循環,但如果事實證明我需要執行多次訪問,那麼我一定會使用這種策略。 – cameronliam

0

可以使用Array.prototype.filter

var document = arr.filter(function(element) { 
    return element.a === '4'; 
}, arr)[0]; 

console.log(document); 
+1

儘管數組中的所有元素仍然在循環。OP要求一種「不循環數組中的所有元素」的方法。 – jfriend00

+0

我知道這可能是一個解決方案,不明確使用循環。我們不知道運營商究竟想要什麼.. –

+0

是的,對不起,應該是更具體。爲了表現,我想避免完全循環。但是,在這種情況下似乎是不可避免的。不管怎麼說,還是要謝謝你。 – cameronliam

0

也許你應該閱讀關於binary search algorithm。互聯網上有很多JS實現。

+1

二進制搜索只能在數據按正在查找的值正確排序時才能使用。 – jfriend00

+0

我知道。我認爲這個算法會很有幫助,因爲在你的代碼中,所有'a'按升序排列。 –

+0

對不起,這是我的一個不好的例子。數據實際上並未按任何順序排列,而值'1,2,3 ...'也可以是字符串。但謝謝你的迴應。 – cameronliam

0

如果你只需要由「A」鍵來訪問數組中的對象,並且可以調整你的數組作爲JSON對象,你可以這樣做:

var jsonObj = { 
    '1': { b: '2', c: '3' }, 
    '4': { b: '5', c: '6'}, 
    .... 
} 

然後你可以檢索像這樣的「1」鍵的對象:

jsonObj['1'] 

(請注意,號碼JSON作爲密鑰無效,所以你不能將能夠使用jsonObj.1)

+0

不幸的是,我從數據庫中檢索這種形式的數組,所以重組不是一種選擇,但謝謝。 – cameronliam