简体   繁体   中英

Efficient way to access document by key in inside array of documents?

In JavaScript, I need an efficient way to access a document in an array that has the following form:

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

So, all the documents have the same keys. If I have the value for a (for example a = 4 ), is there a way to retrieve the document where a = 4 from the array without looping through all elements in the array and performing the check?

With just the data structure you show, there is no way to retrieve the object where the key a is === '4' without some code that loops through the array. Arrays don't have have any powers to find content in nested objects within them without looping.

It would be possible to build a separate index of that array or to restructure the data into a different type of data structure that would then allow you to retrieve the desired item without looping, but not as you have the data structured there.

For example, you could loop over the array once and build an index of all the values of a present in the array such that with one access from that index, you could know which array elements contain the desired value of a . But, you'd have to first build that type of index before you could use it. If this was a one time access, that wouldn't save you any time, but if you were going to be looking up values of a over and over again, it could save a lot of time. Build the index once, then use it many times to improve the efficiency of finding a specific value.


To make a more efficient way of finding data if the array is large, here's a scheme for indexing the data once and then using that index many times after that. This assumes the data is a string or has a non-ambiguous string conversion (which your example fits):

 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); } 

You can use the Array.prototype.filter

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

console.log(document);

Maybe you should read about binary search algorithm . There are many JS implementations on the Internet.

If you only need to access objects in the array by the 'a' key, and it is possible to restructure your array as a JSON Object, you could do this:

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

Then you can retrieve the object with the '1' key like this:

jsonObj['1']

(Note that numbers in JSON as keys aren't valid, so you wouldn't be able to use jsonObj.1)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM