在对象数组中,找到属性匹配搜索的对象的索引的最快方法

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

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

我想要做的是找到对象的 INDEXES,其中 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);

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

233844 次浏览
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);
}
}

在我看来,您可以创建一个带有回调的简单迭代器来进行测试:

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

新的 Array 方法 。过滤()可以很好地解决这个问题:

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

JQuery 也可以通过 。 grep ()实现这一点

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

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

var elementPos = array.map(function(x) {return x.id; }).indexOf(idYourAreLookingFor);
var objectFound = array[elementPos];
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 我们得到记录的索引。

将 Tejs 的答案改编为 mongoDB 和 Robomongo,我做了修改

matchingIndices.push(j);

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

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

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)

由于我还不能发表评论,我想展示一下我使用的基于 Umair Ahmed 发布的方法的解决方案,但是当你想搜索一个键而不是一个值时:

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

我知道它没有回答这个扩展的问题,但是标题没有明确说明每个对象想要什么,所以我想谦虚地分享这个,以免将来给其他人带来麻烦,虽然我重启它可能不是最快的解决方案。

使用 ES6 map功能:

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

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


console.log(found === two) // true


console.log(arr.indexOf(found)) // 1

为了总结上面所有的答案和我关于找到所有索引的附加答案,我从一些评论中找到了所有的索引。

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

我已经创建了一个名为 超级数组的小实用程序,可以通过一个复杂度为 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'}
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)

一种使用 ES6的新方法

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

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

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

下面的示例演示了最快的方法。 给你是到实际测试的链接

设置块

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

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

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

根据特定匹配查找数组中对象的索引的一个简单方法。

//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

正如@PirateBay 指出的那样,有时候老办法是最好的。

与 ES 6/7“ . find”是非常快的太和停止时,它匹配(不同于。地图或。过滤器)

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