获取数组内对象的索引,与条件匹配

2022-08-29 23:09:03

我有一个这样的数组:

[{prop1:"abc",prop2:"qwe"},{prop1:"bnmb",prop2:"yutu"},{prop1:"zxvz",prop2:"qwrq"},...]

如何获取与条件匹配的对象的索引,而不循环访问整个数组?

例如,给定 ,我想获取索引 。prop2=="yutu"1

我看到但认为它用于简单的数组,如.我也检查了,但这返回对象,而不是索引。.indexOf()["a1","a2",...]$.grep()


答案 1

截至2016年,您应该使用Array.findIndex(ES2015 / ES6标准)来实现以下目的:

a = [
  {prop1:"abc",prop2:"qwe"},
  {prop1:"bnmb",prop2:"yutu"},
  {prop1:"zxvz",prop2:"qwrq"}];
    
index = a.findIndex(x => x.prop2 ==="yutu");

console.log(index);

它在Google Chrome,Firefox和Edge中受支持。对于 Internet Explorer,链接页面上有一个 polyfill。

性能说明

函数调用是昂贵的,因此对于非常大的数组,简单的循环将比以下代码表现得好得多:findIndex

let test = [];

for (let i = 0; i < 1e6; i++)
    test.push({prop: i});


let search = test.length - 1;
let count = 100;

console.time('findIndex/predefined function');
    let fn = obj => obj.prop === search;

    for (let i = 0; i < count; i++)
        test.findIndex(fn);
console.timeEnd('findIndex/predefined function');


console.time('findIndex/dynamic function');
    for (let i = 0; i < count; i++)
        test.findIndex(obj => obj.prop === search);
console.timeEnd('findIndex/dynamic function');


console.time('loop');
    for (let i = 0; i < count; i++) {
        for (let index = 0; index < test.length; index++) {
            if (test[index].prop === search) {
                break;
            }
        }
    }
console.timeEnd('loop');

与大多数优化一样,这应该小心应用,并且仅在实际需要时才应用。


答案 2

如何获取匹配条件的对象的索引(不沿数组迭代)?

你不能,某些东西必须遍历数组(至少一次)。

如果条件变化很大,那么你必须循环查看其中的对象,看看它们是否符合条件。但是,在具有 ES5 功能的系统(或者如果安装填充程序)上,可以相当简洁地完成该迭代:

var index;
yourArray.some(function(entry, i) {
    if (entry.prop2 == "yutu") {
        index = i;
        return true;
    }
});

它使用 new(ish) Array#some 函数,该函数循环遍历数组中的条目,直到您为其提供的函数返回 true。我给它的函数保存匹配条目的索引,然后返回以停止迭代。true

或者,当然,只使用一个循环。您的各种迭代选项将在另一个答案中介绍。for

但是,如果您始终要对此查找使用相同的属性,并且属性值是唯一的,则可以只循环一次并创建一个对象来映射它们:

var prop2map = {};
yourArray.forEach(function(entry) {
    prop2map[entry.prop2] = entry;
});

(或者,同样,您可以使用循环或任何其他选项for

然后,如果您需要使用 找到条目,则可以执行以下操作:prop2 = "yutu"

var entry = prop2map["yutu"];

我称之为“交叉索引”数组。当然,如果删除或添加条目(或更改其值),则还需要更新映射对象。prop2