Reputation: 1218
A number of times (especially in MVC scenarios) I had to use an array to store objects, but I also had to access the objects by a property of the stored objects. I may then iterate the array, but I guess (guess because I really know little about Javascript performance) this will be slow already with hundreds of objects and hundreds of iterations. I then build an index like so:
var arr = [];
var index = {};
var o1 = {id: 0, key: "A", data: "X"};
var o2 = {id: 1, key: "B", data: "Y"};
arr.push(o1);
arr.push(o2);
index[o1.key] = o1;
index[o2.key] = o2;
var lookupKey = "B";
// modify object
arr[1].data = "Z";
// get data for key "B" - alerts "Z"
alert(index[lookupKey].data);
(http://jsfiddle.net/timvdh/WT53x/3/)
Of course I have to build and maintain this index... I was wondering if there is a better method?
I guess there is a lib that includes "SortedDictionaries" (the name of such generic collection in .NET) - and I would like to know about is. However, I am also working with specialized arrays (e.g. knockout's observableArray) and I would need a way to index that array, too. Or I need to know that it is simply not worth doing what I am doing with the index.
Upvotes: 1
Views: 280
Reputation: 1305
The best solution I see is, sure, iterate the array.
ECMAScript 6 may introduce the find() method. Until then, ou may create a simple function as bellow (not tested):
function obj_find(arr, key, value) {
for (var i = 0; i < arr.length; i++) {
if (arr[i][key] == value) return arr[i];
}
return null;
}
I don't think it'll slow down too much your app, since the function returns as soon as it finds the value. But you have thousands of elements to search you may add a cache to speed up the function.
Upvotes: 0
Reputation: 63524
Sounds like you're heading in the right direction, but there's a couple of tricks you can employ to get the answer you need without building a separate index.
var arr = [];
arr.push({id: 0, key: "A", data: "X"});
arr.push({id: 1, key: "B", data: "Y"});
arr[1].data = 'Z';
var lookup = 'B';
Now here you can use the filter
method* on the array to pull out the object with the correct lookup value.
var result = arr.filter(function(el) {
return el.key === lookup;
});
Note that results
will be an array of all the matches that are found. So, if you only have one element in the array:
console.log(result[0].data) // Z
Let's add another object to the array and rerun the filter:
arr.push({id: 2, key: "B", data: "E"});
And use a loop on the results:
for (var i = 0, l = result.length; i < l; i++) {
console.log(result[i].data); // Z and E
}
Ultimately you might want to encapsulate this into a function like so:
function findThings(prop, value) {
return arr.filter(function(el) {
return el[prop] === value;
});
}
console.log(findThings('key', 'B')) // an array of two objects that you can loop over
* Note that for older browers you'll need to use a filter
polyfill.
Upvotes: 1