Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get the index of the object inside an array, matching a condition

I have an array like this:

[{prop1:"abc",prop2:"qwe"},{prop1:"bnmb",prop2:"yutu"},{prop1:"zxvz",prop2:"qwrq"},...] 

How can I get the index of the object that matches a condition, without iterating over the entire array?

For instance, given prop2=="yutu", I want to get index 1.

I saw .indexOf() but think it's used for simple arrays like ["a1","a2",...]. I also checked $.grep() but this returns objects, not the index.

like image 596
amp Avatar asked Apr 14 '13 10:04

amp


People also ask

How do you get an index of an item in an array?

To find the position of an element in an array, you use the indexOf() method. This method returns the index of the first occurrence the element that you want to find, or -1 if the element is not found.

How do you find the index of an object in an array in TypeScript?

The Array. indexOf() is an inbuilt TypeScript function which is used to find the index of the first occurrence of the search element provided as the argument to the function.

Can you use indexOf for an array?

IndexOf(Array, Object, Int32) Searches for the specified object in a range of elements of a one-dimensional array, and returns the index of its first occurrence. The range extends from a specified index to the end of the array.

How do I find a particular index of an element?

Given an array of N elements and an element K, find the index of an array element in Java. An element in an array of N integers can be searched using the below-mentioned methods. Linear Search: Doing a linear search in an array, the element can be found in O(N) complexity.


2 Answers

As of 2016, you're supposed to use Array.findIndex (an ES2015/ES6 standard) for this:

a = [    {prop1:"abc",prop2:"qwe"},    {prop1:"bnmb",prop2:"yutu"},    {prop1:"zxvz",prop2:"qwrq"}];        index = a.findIndex(x => x.prop2 ==="yutu");    console.log(index);

It's supported in Google Chrome, Firefox and Edge. For Internet Explorer, there's a polyfill on the linked page.

Performance note

Function calls are expensive, therefore with really big arrays a simple loop will perform much better than findIndex:

let test = [];    for (let i = 0; i < 1e6; i++)      test.push({prop: i});      let search = test.length - 1;  let count = 100;    console.time('findIndex/predefined function');      let fn = obj => obj.prop === search;        for (let i = 0; i < count; i++)          test.findIndex(fn);  console.timeEnd('findIndex/predefined function');      console.time('findIndex/dynamic function');      for (let i = 0; i < count; i++)          test.findIndex(obj => obj.prop === search);  console.timeEnd('findIndex/dynamic function');      console.time('loop');      for (let i = 0; i < count; i++) {          for (let index = 0; index < test.length; index++) {              if (test[index].prop === search) {                  break;              }          }      }  console.timeEnd('loop');

As with most optimizations, this should be applied with care and only when actually needed.

like image 123
12 revs, 4 users 95% Avatar answered Sep 21 '22 04:09

12 revs, 4 users 95%


How can I get the index of the object tha match a condition (without iterate along the array)?

You cannot, something has to iterate through the array (at least once).

If the condition changes a lot, then you'll have to loop through and look at the objects therein to see if they match the condition. However, on a system with ES5 features (or if you install a shim), that iteration can be done fairly concisely:

var index; yourArray.some(function(entry, i) {     if (entry.prop2 == "yutu") {         index = i;         return true;     } }); 

That uses the new(ish) Array#some function, which loops through the entries in the array until the function you give it returns true. The function I've given it saves the index of the matching entry, then returns true to stop the iteration.

Or of course, just use a for loop. Your various iteration options are covered in this other answer.

But if you're always going to be using the same property for this lookup, and if the property values are unique, you can loop just once and create an object to map them:

var prop2map = {}; yourArray.forEach(function(entry) {     prop2map[entry.prop2] = entry; }); 

(Or, again, you could use a for loop or any of your other options.)

Then if you need to find the entry with prop2 = "yutu", you can do this:

var entry = prop2map["yutu"]; 

I call this "cross-indexing" the array. Naturally, if you remove or add entries (or change their prop2 values), you need to update your mapping object as well.

like image 24
T.J. Crowder Avatar answered Sep 21 '22 04:09

T.J. Crowder