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

时间:2012-05-11 19:30:19

标签: javascript arrays indexof

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

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,因为它可能应该。 提前谢谢!

19 个答案:

答案 0 :(得分:362)

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

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

答案 1 :(得分:51)

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

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)

答案 2 :(得分:25)

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

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

jQuery也可以使用.grep()

执行此操作

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

答案 3 :(得分:7)

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,我们得到记录的索引。

答案 4 :(得分: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);
    }
}

答案 5 :(得分:5)

由于使用常规数组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

答案 6 :(得分:3)

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

以下是演示最快方法的示例。 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);

答案 7 :(得分:3)

使用ES6的新方法

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

答案 8 :(得分: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

答案 9 :(得分: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);

答案 10 :(得分:2)

总结以上所有优秀答案以及我的答案,其中包括从某些评论中找到所有索引。

  1. 返回第一次出现的索引。
  2. 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。
    2. 返回所有实例的索引数组

      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, [])

答案 11 :(得分:2)

使用ES6 map功能:

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

答案 12 :(得分:2)

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

matchingIndices.push(j);

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

答案 13 :(得分: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'}

答案 14 :(得分: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中有效)

答案 15 :(得分:0)

由于我无法发表评论,我想根据Umair Ahmed发布的方法显示我使用的解决方案,但是当您想要搜索密钥而不是值时:

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

我知道它没有回答扩展的问题,但是标题并没有指定每个对象的内容,所以我想谦虚地分享这个以避免将来给别人带来麻烦,同时我不开始它可能不是最快的解决方案。

答案 16 :(得分:0)

我喜欢这种方法,因为无论嵌套的深度如何,都可以轻松地将其与对象中的任何值进行比较。

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

答案 17 :(得分:0)

一种基于特定匹配在数组中查找对象索引的简单方法。

//list of bookings
const bookings = [
    { status: "accepted", _id: "6055cadd062eb5153c089121", title: "This is test title", user: "id", team: "id" },
    { status: "pending", _id: "6055cb33062eb5153c089122", title: "title1", description: "test description", user: "id", team: "id" },
    { status: "accepted", _id: "6055cb3d062eb5153c089123", title: "title2", description: "test description", user: "id", team: "id" }
]

//return index of the element if find else return -1 
const findIndex = (booking) => bookings.findIndex((b, index) => {
    if (b._id === booking._id) return true
})

//test 1
let booking = { status: "pending", _id: "6055cb33062eb5153c089122", title: "title2", description: "test description", user: "id", team: "id" }
console.log("index >>> ", findIndex(booking))
//output : 1

//test 2
booking = { status: "rejected", _id: "6055cb33062eb5153c089198", title: "title3", description: "test description", user: "id", team: "id" }
console.log("index >>> ", findIndex(booking))
//output : -1

//test 3
const id = '6055cb3d062eb5153c089123'
console.log("index >>> ", findIndex({ _id: id }))
//output : 2

find-searchElementInArrayObObjects

答案 18 :(得分:0)

正如@PirateBay 指出的那样,有时旧的方法是最好的。

使用 ES 6/7,“.find”也非常快并且在匹配时停止(与 .map 或 .filter 不同)

items.find(e => e.id === find)?.id