[javascript] In an array of objects, fastest way to find the index of an object whose attributes match a search

I've been surfing around a little trying to find an efficient way to do this, but have gotten nowhere. I have an array of objects that looks like this:

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

What i want to do is to find the INDEXES of the objects where id is equal to, for example, one of 0,1,2,3 or 4. I suppose I could just do something like :

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

While this would work, it looks to be quite expensive and slow (not to mention ugly), especially if array.length could be large. Any ideas on how to spruce this up a bit? I thought of using array.indexOf somehow but I don't see how to force the syntax. This

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

for example, returns undefined, as it probably should. Thanks in advance!

This question is related to javascript arrays indexof

The answer is


The simplest and easiest way to find element index in array.

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

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


The new Array method .filter() would work well for this:

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

jQuery can also do this with .grep()

edit: it is worth mentioning that both of these functions just iterate under the hood, there won't be a noticeable performance difference between them and rolling your own filter function, but why re-invent the wheel.


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

will return index 1 (Works only in ES 2016)


Using the ES6 map function:

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

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

the result is a look up list for the id. with the given id we get the index of the record.


Since there's no answer using regular array 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

If you care about performance, dont go with find or filter or map or any of the above discussed methods

Here is an example demonstrating the fastest method. HERE is the link to the actual test

Setup block

var items = []

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

var find = 523

Fastest Method

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

Slower Methods

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

SLOWEST method

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

A new way using ES6

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

I've created a tiny utility called super-array where you can access items in an array by a unique identifier with O(1) complexity. Example:

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'}

As I can't comment yet, I want to show the solution I used based on the method Umair Ahmed posted, but when you want to search for a key instead of a value:

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

I understand that it doesn't answer the expanded question, but the title doesn't specify what was wanted from each object, so I want to humbly share this to save headaches to others in the future, while I undestart it may not be the fastest solution.


Sounds to me like you could create a simple iterator with a callback for testing. Like so:

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

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

    return matchingIndices;
}

Then you could invoke like so:

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

To summary all of the great answer above and additional of my answer regarding find all the indexes occurred from some of the comment.

  1. To return the index of the first occurrence.

_x000D_
_x000D_
const array = [{ id: 1 }, { id: 2 }, { id: 3 }, { id: 4 }, { id: 2 }];_x000D_
const idYourAreLookingFor = 2;_x000D_
_x000D_
//ES5 _x000D_
//Output: 1_x000D_
array.map(function (x) { return x.id; }).indexOf(idYourAreLookingFor);_x000D_
_x000D_
//ES6 _x000D_
//Output: 1_x000D_
array.findIndex(obj => obj.id === idYourAreLookingFor);
_x000D_
_x000D_
_x000D_

  1. To return the index array of all occurrences, using reduce.

_x000D_
_x000D_
const array = [{ id: 1 }, { id: 2 }, { id: 3 }, { id: 4 }, { id: 2 }]_x000D_
const idYourAreLookingFor = 2;_x000D_
_x000D_
//ES5_x000D_
//Output: [1, 4]_x000D_
array.reduce(function (acc, obj, i) {_x000D_
  if (obj.id === idYourAreLookingFor)_x000D_
    acc.push(i);_x000D_
  return acc;_x000D_
}, []);_x000D_
_x000D_
//ES6_x000D_
//Output: [1, 4]_x000D_
array.reduce((acc, obj, i) => (obj.id === idYourAreLookingFor) ? acc.concat(i) : acc, [])
_x000D_
_x000D_
_x000D_


I like this method because it's easy to compare to any value in the object no matter how deep it's nested.

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

Adapting Tejs's answer for mongoDB and Robomongo I changed

matchingIndices.push(j);

to

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

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

This should get you the index of item in array with id === your-id

_x000D_
_x000D_
array = [ {id:1}, {id:2} ];_x000D_
_x000D_
const index = array.findIndex(item => item.id === 2);_x000D_
_x000D_
console.log(index);
_x000D_
_x000D_
_x000D_


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

Examples related to javascript

need to add a class to an element How to make a variable accessible outside a function? Hide Signs that Meteor.js was Used How to create a showdown.js markdown extension Please help me convert this script to a simple image slider Highlight Anchor Links when user manually scrolls? Summing radio input values How to execute an action before close metro app WinJS javascript, for loop defines a dynamic variable name Getting all files in directory with ajax

Examples related to arrays

PHP array value passes to next row Use NSInteger as array index How do I show a message in the foreach loop? Objects are not valid as a React child. If you meant to render a collection of children, use an array instead Iterating over arrays in Python 3 Best way to "push" into C# array Sort Array of object by object field in Angular 6 Checking for duplicate strings in JavaScript array what does numpy ndarray shape do? How to round a numpy array?

Examples related to indexof

Uncaught TypeError: .indexOf is not a function indexOf and lastIndexOf in PHP? Finding second occurrence of a substring in a string in Java Index of element in NumPy array Getting Index of an item in an arraylist; In an array of objects, fastest way to find the index of an object whose attributes match a search Get value of a string after last slash in JavaScript How to find the array index with a value? Where is Java's Array indexOf? How to trim a file extension from a String in JavaScript?