在对象数组中,以最快的方式查找属性与搜索匹配的对象的索引

问题描述 投票:124回答:17

我一直在尝试寻找一种有效的方法来进行冲浪,但却无处可去。我有一个对象数组,如下所示:

array[i].id = some number;
array[i].name = some name;

我想要做的是找到id等于的对象的INDEXES,例如,0,1,2,3或4中的一个。我想我可以做类似的事情:

var indexes = [];
for(i=0; i<array.length; i++) {
  (array[i].id === 0) ? { indexes[0] = i }
  (array[i].id === 1) ? { indexes[1] = i }
  (array[i].id === 2) ? { indexes[2] = i }
  (array[i].id === 3) ? { indexes[3] = i }
  (array[i].id === 4) ? { indexes[4] = i }
}

虽然这可行,但它看起来相当昂贵且缓慢(更不用说丑陋),特别是如果array.length可能很大。关于如何修饰这一点的任何想法?我想过以某种方式使用array.indexOf,但我没有看到如何强制语法。这个

array.indexOf(this.id === 0);

例如,返回undefined,因为它可能应该。提前致谢!

javascript arrays indexof
17个回答
365
投票

也许你想使用更高阶的函数,比如“map”。假设您想通过'field'属性进行搜索:

var elementPos = array.map(function(x) {return x.id; }).indexOf(idYourAreLookingFor);
var objectFound = array[elementPos];

2
投票

改编Tejs对mongoDB和Robomongo的回答我改变了

matchingIndices.push(j);

matchingIndices.push(NumberInt(j+1));

2
投票

使用ES6 map功能:

let idToFind = 3;
let index = someArray.map(obj => obj.id).indexOf(idToFind);

2
投票

总结一下上面的所有重要答案,以及关于查找从某些评论中发现的所有索引的其他答案。

  1. 返回第一次出现的索引。

const array = [{ id: 1 }, { id: 2 }, { id: 3 }, { id: 4 }, { id: 2 }];
const idYourAreLookingFor = 2;

//ES5 
//Output: 1
array.map(function (x) { return x.id; }).indexOf(idYourAreLookingFor);

//ES6 
//Output: 1
array.findIndex(obj => obj.id === idYourAreLookingFor);
  1. 要使用reduce返回所有实例的索引数组。

const array = [{ id: 1 }, { id: 2 }, { id: 3 }, { id: 4 }, { id: 2 }]
const idYourAreLookingFor = 2;

//ES5
//Output: [1, 4]
array.reduce(function (acc, obj, i) {
  if (obj.id === idYourAreLookingFor)
    acc.push(i);
  return acc;
}, []);

//ES6
//Output: [1, 4]
array.reduce((acc, obj, i) => (obj.id === idYourAreLookingFor) ? acc.concat(i) : acc, [])

2
投票

const index = array.findIndex(item => item.id === 'your-id');

这应该为您获取数组中项目的索引,其ID为=== your-id

array = [ {id:1}, {id:2} ];

const index = array.findIndex(item => item.id === 2);

console.log(index);

0
投票

由于我还没有评论,我想根据Umair Ahmed发布的方法显示我使用的解决方案,但是当你想要搜索一个键而不是一个值时:

[{"a":true}, {"f":true}, {"g":false}]
.findIndex(function(element){return Object.keys(element)[0] == "g"});

我知道它没有回答扩展的问题,但是标题没有说明每个对象想要什么,所以我想谦卑地分享这个以便将来给别人带来麻烦,而我不能开始它可能不是最快解决方案


0
投票

我创建了一个名为super-array的小工具,您可以通过O(1)复杂性的唯一标识符访问数组中的项目。例:

const SuperArray = require('super-array');

const myArray = new SuperArray([
  {id: 'ab1', name: 'John'},
  {id: 'ab2', name: 'Peter'},
]);

console.log(myArray.get('ab1')); // {id: 'ab1', name: 'John'}
console.log(myArray.get('ab2')); // {id: 'ab2', name: 'Peter'}

0
投票
var test = [
  {id:1, test: 1},
  {id:2, test: 2},
  {id:2, test: 2}
];

var result = test.findIndex(findIndex, '2');

console.log(result);

function findIndex(object) {
  return object.id == this;
}

将返回索引1(仅在ES 2016中有效)


0
投票

我喜欢这种方法,因为无论对象有多深,它都很容易与对象中的任何值进行比较。

 while(i<myArray.length && myArray[i].data.value!==value){
  i++; 
}
// i now hows the index value for the match. 
 console.log("Index ->",i );

53
投票

在数组中查找元素索引的最简单,最简单的方法。

ES5语法:[{id:1},{id:2},{id:3},{id:4}].findIndex(function(obj){return obj.id == 3})

ES6语法:[{id:1},{id:2},{id:3},{id:4}].findIndex(obj => obj.id == 3)


25
投票

新的Array方法.filter()适用于此:

var filteredArray = array.filter(function (element) { 
    return element.id === 0;
});

jQuery也可以用.grep()做到这一点

编辑:值得一提的是,这些功能都只是在引擎盖下迭代,它们之间不会有明显的性能差异并且滚动你自己的滤波器功能,但为什么要重新发明轮子。


8
投票
array.forEach(function (elem, i) {  // iterate over all elements of array
    indexes[elem.id] = i;           // take the found id as index for the
});                                 // indexes array and assign i

结果是id的查找列表。使用给定的id,我们得到记录的索引。


6
投票
var indices = [];
var IDs = [0, 1, 2, 3, 4];

for(var i = 0, len = array.length; i < len; i++) {
    for(var j = 0; j < IDs.length; j++) {
        if(array[i].id == ID) indices.push(i);
    }
}

6
投票

由于使用常规数组find没有答案:

var one = {id: 1, name: 'one'};
var two = {id: 2, name:'two'}
var arr = [one, two] 

var found = arr.find((a) => a.id === 2)

found === two // true

arr.indexOf(found) // 1

4
投票

如果您关心性能,请不要使用查找或过滤或映射或任何上述方法

这是一个演示最快方法的示例。 HERE是实际测试的链接

设置块

var items = []

for(var i = 0; i < 1000; i++) {
    items.push({id: i + 1})
}

var find = 523

最快的方法

var index = -1
for(var i = 0; i < items.length; i++) {
    if(items[i].id === find) {
        index = i;
        break;
    }
}

较慢的方法

items.findIndex(item => item.id === find)

最快的方法

items.map(item => item.id).indexOf(find);

3
投票

使用ES6的新方法

let picked_element = array.filter(element => element.id === 0);

2
投票

听起来像你可以创建一个带回调测试的简单迭代器。像这样:

function findElements(array, predicate)
{
    var matchingIndices = [];

    for(var j = 0; j < array.length; j++)
    {
        if(predicate(array[j]))
           matchingIndices.push(j);
    }

    return matchingIndices;
}

然后你可以像这样调用:

var someArray = [
     { id: 1, text: "Hello" },
     { id: 2, text: "World" },
     { id: 3, text: "Sup" },
     { id: 4, text: "Dawg" }
  ];

var matchingIndices = findElements(someArray, function(item)
   {
        return item.id % 2 == 0;
   });

// Should have an array of [1, 3] as the indexes that matched
© www.soinside.com 2019 - 2024. All rights reserved.