多次(特别是在MVC场景中)我不得不使用数组来存储对象,但我还必须通过存储对象的属性来访问对象。然后我可以迭代数组,但我想(猜测因为我对Javascript性能知之甚少)这已经很慢了,有数百个对象和数百个迭代。然后我建立一个像这样的索引:
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/)
当然我必须建立并维护这个索引......我想知道是否有更好的方法?
我猜有一个包含" SortedDictionaries" (.NET中这种通用集合的名称) - 我想知道的是。但是,我也在使用专门的数组(例如,knockout' observableArray),我也需要一种方法来索引该数组。或者我需要知道,对索引做的事情根本就不值得做。
答案 0 :(得分:1)
听起来你正朝着正确的方向前进,但是你可以采用一些技巧来获得你需要的答案,而无需建立单独的索引。
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';
现在,您可以使用数组上的filter
方法*来提取具有正确查找值的对象。
var result = arr.filter(function(el) {
return el.key === lookup;
});
请注意,results
将是找到的所有匹配项的数组。所以,如果你在数组中只有一个元素:
console.log(result[0].data) // Z
让我们在数组中添加另一个对象并重新运行过滤器:
arr.push({id: 2, key: "B", data: "E"});
在结果上使用循环:
for (var i = 0, l = result.length; i < l; i++) {
console.log(result[i].data); // Z and E
}
最终你可能想把它封装成一个像这样的函数:
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
*请注意,对于较旧的浏览器,您需要使用filter
polyfill。
答案 1 :(得分:0)
我看到的最佳解决方案是,确保迭代数组。
ECMAScript 6可能会引入find()方法。在此之前,你可以创建一个简单的函数(未经测试):
function obj_find(arr, key, value) {
for (var i = 0; i < arr.length; i++) {
if (arr[i][key] == value) return arr[i];
}
return null;
}
我不认为它会减慢你的应用程序的速度,因为函数会在找到值后立即返回。但是你有数千个要搜索的元素,你可以添加一个缓存来加速这个功能。