Reputation: 9295
I am using Node v8.1.3
I have a JSON array as following:
[
{
"id":99,
"name": "ABC"
},
{
"id": 187,
"name": "AXZ"
}
]
This array has around 213000 e=objects in it.
Also, the id
s in the objects are not in any order or pattern.
Now, I want to find if a particular id
matches any ID in the array? what is the fastest wait to do it?
I tried
isIdValid(id) {
console.log(id)
return this.list.filter((elem) => {
return elem.id == id
}).length > 0;
}
But this is taking over 4 seconds.
Upvotes: 0
Views: 863
Reputation: 428
One option is to first sort the whole list (or insert it into a binary search tree) which takes some time but is only done once. and from there you can use binary search for the ID which is way faster.
here is a sample bst code for node: js-bst
also here is a package that can be used to query json data list very faster: Defiant
actually creating a hash table is a faster solution than a bst; here is a sample code that does the job:
data = [
{
"id":99,
"name": "ABC"
},
{
"id": 187,
"name": "AXZ"
}
]
var hashCache = {};
data.forEach(function(item){
hashCache[item.id] = item.name
});
// Usage:
var id = '99';
var record = hashCache[id];
if (record) {
alert(record);
} else {
console.log('no match found');
}
you should also consider that this hash table only works if the IDs are unique. otherwise, you need to store a list of names in the hash table for each ID.
Upvotes: 1
Reputation: 2285
These are not the "Most efficient way to check". I'm posting here just as a reference about some ways to prepare the data to have a more performant search by a specific key.
Also is worth considering that in this script, Map
can have a better performance, just because it is the last of all the executions. When its turn comes, V8 would have already been done some optimizations internally. So try to run each of them separately to have better findings.
'use strict';
////////////////////////
// GENERATE TEST DATA //
////////////////////////
const dataSet = [];
let count = 213000;
while(count--) dataSet.push({id: count});
let idToBeFound = 212999;
// //////////////////////////
// // Using Literal Object //
// //////////////////////////
console.time('creatingIndexAsLiteralObject');
const literalObjectKeyedByID = dataSet.map(item => ({[item.id]: true}));
console.timeEnd('creatingIndexAsLiteralObject');
console.time('isIdValidSeekingOnLiteralObject');
console.log('isIdValidSeekingOnLiteralObject :: Found?', isIdValidSeekingOnLiteralObject(idToBeFound, literalObjectKeyedByID));
console.timeEnd('isIdValidSeekingOnLiteralObject');
function isIdValidSeekingOnLiteralObject(id, list) {
return !!list[id];
}
// //////////////////////
// // Using Set Object //
// //////////////////////
console.time('creatingIndexAsSetObject');
const setObject = new Set(dataSet.map(item => item.id));
console.timeEnd('creatingIndexAsSetObject');
console.time('isIdValidSeekingOnSet');
console.log('isIdValidSeekingOnSet :: Found?', isIdValidSeekingOnSet(idToBeFound, setObject));
console.timeEnd('isIdValidSeekingOnSet');
function isIdValidSeekingOnSet(id, list) {
return list.has(id);
}
//////////////////////
// Using Map Object //
//////////////////////
console.time('creatingIndexAsMapObject');
const mapObjectKeyedByID = new Map();
dataSet.forEach(item => mapObjectKeyedByID.set(item.id));
console.timeEnd('creatingIndexAsMapObject');
console.time('isIdValidSeekingOnMap');
console.log('isIdValidSeekingOnMap :: Found?', isIdValidSeekingOnMap(idToBeFound, mapObjectKeyedByID));
console.timeEnd('isIdValidSeekingOnMap');
function isIdValidSeekingOnMap(id, list) {
return list.has(id);
}
Upvotes: 0