156

我一直在四处寻找一种有效的方法来做到这一点,但一无所获。我有一个看起来像这样的对象数组:

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

我想要做的是找到 id 等于的对象的索引,例如,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);

例如,返回未定义的,因为它可能应该。

4

19 回答 19

419

也许您想使用诸如“地图”之类的高阶函数。假设您要按“字段”属性搜索:

var elementPos = array.map(function(x) {return x.id; }).indexOf(idYourAreLookingFor);
var objectFound = array[elementPos];
于 2013-04-19T08:28:51.800 回答
90

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

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)

于 2016-12-21T10:21:58.717 回答
26

新的 Array 方法.filter()可以很好地解决这个问题:

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

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

编辑:值得一提的是,这两个函数都只是在底层迭代,它们与滚动你自己的过滤器函数之间不会有明显的性能差异,但为什么要重新发明轮子。

于 2012-05-11T19:37:18.183 回答
17

如果您关心性能,请不要使用findfiltermap或任何上述方法

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

设置块

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);
于 2019-03-16T16:31:51.760 回答
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 我们得到记录的索引。

于 2015-04-08T17:05:06.323 回答
7

由于使用常规数组没有答案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
于 2017-06-08T20:44:35.820 回答
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);
    }
}
于 2012-05-11T19:34:00.660 回答
6

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

于 2018-07-19T06:58:57.757 回答
4

一种使用 ES6 的新方式

let picked_element = array.filter(element => element.id === 0);
于 2018-01-24T22:40:09.880 回答
3

使用 ES6map函数:

let idToFind = 3;
let index = someArray.map(obj => obj.id).indexOf(idToFind);
于 2017-06-08T20:22:39.627 回答
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
于 2012-05-11T19:35:06.160 回答
2

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

matchingIndices.push(j);

matchingIndices.push(NumberInt(j+1));
于 2015-07-19T18:23:56.087 回答
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, [])

于 2017-08-15T09:27:34.907 回答
1

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

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

items.find(e => e.id === find)?.id
于 2021-08-04T04:35:55.437 回答
1

我创建了一个名为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'}
于 2017-09-24T17:46:08.953 回答
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

查找-searchElementInArrayObObjects

于 2021-04-13T20:14:54.193 回答
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 中有效)

于 2017-11-01T10:03:08.057 回答
0

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

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

我知道它没有回答扩展的问题,但标题并没有说明每个对象想要什么,所以我想谦虚地分享这个,以便将来让其他人头疼,而我取消它可能不是最快的解决方案。

于 2017-02-02T13:46:06.837 回答
0

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

 while(i<myArray.length && myArray[i].data.value!==value){
  i++; 
}
// i now hows the index value for the match. 
 console.log("Index ->",i );
于 2019-04-05T14:07:13.180 回答