How to find index of an object by key and value in an javascript array

JavascriptJquery

Javascript Problem Overview


Given:

var peoples = [
  { "attr1": "bob", "attr2": "pizza" },
  { "attr1": "john", "attr2": "sushi" },
  { "attr1": "larry", "attr2": "hummus" }
];

Wanted:

Index of object where attr === value for example attr1 === "john" or attr2 === "hummus"

Update: Please, read my question carefully, i do not want to find the object via $.inArray nor i want to get the value of a specific object attribute. Please consider this for your answers. Thanks!

Javascript Solutions


Solution 1 - Javascript

The Functional Approach

All the cool kids are doing functional programming (hello React users) these days so I thought I would give the functional solution. In my view it's actually a lot nicer than the imperatival for and each loops that have been proposed thus far and with ES6 syntax it is quite elegant.

Update

There's now a great way of doing this called findIndex which takes a function that return true/false based on whether the array element matches (as always, check for browser compatibility though).

var index = peoples.findIndex(function(person) {
  return person.attr1 == "john"
});

With ES6 syntax you get to write this:

var index = peoples.findIndex(p => p.attr1 == "john");

The (Old) Functional Approach

TL;DR

If you're looking for index where peoples[index].attr1 == "john" use:

var index = peoples.map(function(o) { return o.attr1; }).indexOf("john");

Explanation

Step 1

Use .map() to get an array of values given a particular key:

var values = object_array.map(function(o) { return o.your_key; });

The line above takes you from here:

var peoples = [
  { "attr1": "bob", "attr2": "pizza" },
  { "attr1": "john", "attr2": "sushi" },
  { "attr1": "larry", "attr2": "hummus" }
];

To here:

var values = [ "bob", "john", "larry" ];

Step 2

Now we just use .indexOf() to find the index of the key we want (which is, of course, also the index of the object we're looking for):

var index = values.indexOf(your_value);

Solution

We combine all of the above:

var index = peoples.map(function(o) { return o.attr1; }).indexOf("john");

Or, if you prefer ES6 syntax:

var index = peoples.map((o) => o.attr1).indexOf("john");

Demo:

var peoples = [
  { "attr1": "bob", "attr2": "pizza" },
  { "attr1": "john", "attr2": "sushi" },
  { "attr1": "larry", "attr2": "hummus" }
];

var index = peoples.map(function(o) { return o.attr1; }).indexOf("john");
console.log("index of 'john': " + index);

var index = peoples.map((o) => o.attr1).indexOf("larry");
console.log("index of 'larry': " + index);

var index = peoples.map(function(o) { return o.attr1; }).indexOf("fred");
console.log("index of 'fred': " + index);

var index = peoples.map((o) => o.attr2).indexOf("pizza");
console.log("index of 'pizza' in 'attr2': " + index);

Solution 2 - Javascript

If you want to check on the object itself without interfering with the prototype, use hasOwnProperty():

var getIndexIfObjWithOwnAttr = function(array, attr, value) {
    for(var i = 0; i < array.length; i++) {
        if(array[i].hasOwnProperty(attr) && array[i][attr] === value) {
            return i;
        }
    }
    return -1;
}

to also include prototype attributes, use:

var getIndexIfObjWithAttr = function(array, attr, value) {
    for(var i = 0; i < array.length; i++) {
        if(array[i][attr] === value) {
            return i;
        }
    }
    return -1;
}

Solution 3 - Javascript

Using jQuery .each()

var peoples = [
  { "attr1": "bob", "attr2": "pizza" },
  { "attr1": "john", "attr2": "sushi" },
  { "attr1": "larry", "attr2": "hummus" }
];

$.each(peoples, function(index, obj) {
   $.each(obj, function(attr, value) {
      console.log( attr + ' == ' + value );
   });
});

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

Using for-loop:

var peoples = [  { "attr1": "bob", "attr2": "pizza" },  { "attr1": "john", "attr2": "sushi" },  { "attr1": "larry", "attr2": "hummus" }];

for (var i = 0; i < peoples.length; i++) {
  for (var key in peoples[i]) {
    console.log(key + ' == ' + peoples[i][key]);
  }
}

Solution 4 - Javascript

Not a direct answer to your question, though I thing it's worth mentioning it, because your question seems like fitting in the general case of "getting things by name in a key-value storage".

If you are not tight to the way "peoples" is implemented, a more JavaScript-ish way of getting the right guy might be :

var peoples = {
  "bob":  { "dinner": "pizza" },
  "john": { "dinner": "sushi" },
  "larry" { "dinner": "hummus" }
};

// If people is implemented this way, then
// you can get values from their name, like :
var theGuy = peoples["john"];

// You can event get directly to the values
var thatGuysPrefferedDinner = peoples["john"].dinner;

Hope if this is not the answer you wanted, it might help people interested in that "key/value" question.

Solution 5 - Javascript

function getIndexByAttribute(list, attr, val){
    var result = null;
    $.each(list, function(index, item){
        if(item[attr].toString() == val.toString()){
           result = index;
           return false;     // breaks the $.each() loop
        }
    });
    return result;
}

Solution 6 - Javascript

You can also make it a reusable method by expending JavaScript:

Array.prototype.findIndexBy = function(key, value) {
    return this.findIndex(item => item[key] === value)
}

const peoples = [{name: 'john'}]
const cats = [{id: 1, name: 'kitty'}]

peoples.findIndexBy('name', 'john')
cats.findIndexBy('id', 1)

Solution 7 - Javascript

Do this way:-

var peoples = [
  { "name": "bob", "dinner": "pizza" },
  { "name": "john", "dinner": "sushi" },
  { "name": "larry", "dinner": "hummus" }
];

$.each(peoples, function(i, val) {
    $.each(val, function(key, name) {
        if (name === "john")
            alert(key + " : " + name);
    });
});

OUTPUT:

name : john

Refer LIVE DEMO

ā€‹

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionreturn1.atView Question on Stackoverflow
Solution 1 - JavascriptjcuenodView Answer on Stackoverflow
Solution 2 - Javascriptreturn1.atView Answer on Stackoverflow
Solution 3 - JavascriptthecodeparadoxView Answer on Stackoverflow
Solution 4 - JavascriptAlain BECKERView Answer on Stackoverflow
Solution 5 - JavascriptdavidsView Answer on Stackoverflow
Solution 6 - JavascriptTychoView Answer on Stackoverflow
Solution 7 - JavascriptSiva CharanView Answer on Stackoverflow