使用附加键可以访问Javascript数组元素

时间:2014-03-13 12:21:05

标签: javascript arrays dictionary

多次(特别是在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),我也需要一种方法来索引该数组。或者我需要知道,对索引做的事情根本就不值得做。

2 个答案:

答案 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
}

Fiddle

最终你可能想把它封装成一个像这样的函数:

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

我不认为它会减慢你的应用程序的速度,因为函数会在找到值后立即返回。但是你有数千个要搜索的元素,你可以添加一个缓存来加速这个功能。