I've got an array:

myArray = [{'id':'73','foo':'bar'},{'id':'45','foo':'bar'},etc.]

I'm unable to change the structure of the array. I'm being passed an ID#, e.g. '45', and I want to get 'bar' for that object in the array. What's the best way? Thanks!

share|improve this question

11 Answers

up vote 84 down vote accepted

The grep function is intended for searching an array:

var result = $.grep(myArray, function(e){ return e.id == id; });

The result is an array with the items found. If you know that the object is always there and that it only occurs once, you can just use result[0].foo to get the value. Otherwise you should check the length of the resulting array. Example:

if (result.length == 0) {
  // not found
} else if (result.length == 1) {
  // access the foo property using result[0].foo
} else {
  // multiple items found
}
share|improve this answer
1  
It'd be safer to use === instead of ==, to avoid weird issues with JavaScript's == operator. – Vicky Chijwani Dec 11 '12 at 12:03
@VickyChijwani: Are there any issues when comparing a string to a string? – Guffa Dec 11 '12 at 12:17
Well, if you're absolutely sure that both e.id and id will be strings, I suppose it's ok to use ==. But if you're not sure, you might face problems (since '' == 0 is true but '' === 0 is false). Not to mention === seems to be faster (stackoverflow.com/questions/359494/…). – Vicky Chijwani Dec 11 '12 at 13:19
4  
Basically I always use === because it works exactly like == in other programming languages. I consider == to be non-existent in JavaScript. – Vicky Chijwani Dec 11 '12 at 13:27
I had to use ==, didn't look it deeper, but guessing it was because I was comparing month values and other value could be 01 and other 1. In my case they were the same. – Jussi Palo Jan 10 at 9:29
show 1 more comment

Try the following

function findById(source, id) {
  for (var i = 0; i < source.length; i++) {
    if (source[i].id === id) {
      return source[i];
    }
  }
  throw "Couldn't find object with id: " + id;
}
share|improve this answer
5  
This wasn't worthy of its own answer, but in modern browsers this solution can be written as: jsfiddle.net/rwaldron/j3vST – Rick Sep 9 '11 at 15:50
@Rick thanks for the example. Very useful. – thugsb Sep 9 '11 at 18:16

Another solution is to create a lookup object:

var lookup = {};
for (var i = 0, len = array.length; i < len; i++) {
    lookup[array[i].id] = array[i];
}

... now you can use lookup[id]...

This is especially interesting if you need to do many lookups.

This won't need much more memory since the IDs and objects will be shared.

share|improve this answer
that's a really good trick! – stef Dec 30 '12 at 11:11
Exactly what I was looking for. Funny how I was trying to over-complicate it by trying to loop through each time, removing each item from the list as I found it when I only needed to mutate the received data from CouchDB and get it into a format that is useful for my needs. +1 sir! – slickplaid Feb 7 at 17:18
this is smart. I can't imagine how others were convinced by looking all over the array for each use. – Aladdin Homs Feb 20 at 5:52

I think the easiest way would be the following, but it won't work on IE8-:

var result = myArray.filter(function(v) {
    return v.id === '45'; // filter out appropriate one
})[0].foo; // get result and access foo property
share|improve this answer
I'm curious, is there any performance advantage here compared to the usual for? – Igor Zinov'yev Sep 9 '11 at 15:47
@Igor Zinov'yev: Yes, there certainly are performance impacts with those ES5 array tools. A separate function is executed for each element, so it won't be really fast compared to a direct for loop. – pimvdb Sep 9 '11 at 15:48
So you're saying that it would be slower? Also, it will always scan the whole array, as far as I can see, whereas the for loop will terminate on the first match. – Igor Zinov'yev Sep 9 '11 at 15:50
@Igor Zinov'yev: Yes it's a naive solution, I admit. – pimvdb Sep 9 '11 at 15:53
@Igor Zinov'yev thanks for your reasoning. Good to know. – thugsb Sep 9 '11 at 18:18

Underscore.js has a nice method for that:

myArray = [{'id':'73','foo':'bar'},{'id':'45','foo':'bar'},etc.]
obj = _.find(myArray, function(obj) { return obj.id == '45' })
share|improve this answer

Iterate over any item in the array. Every item you visit, check that item's id. If it's a match, return it

If you just want teh codez:

function getId(array, id) {
    for (var i = 0, len = array.length; i < len; i++) {
        if (array[i].id === id) {
            return array[i];
        }
    }
    return null; //nothing found
}

And the same thing using ES5's Array methods:

function getId(array, id) {
    var obj = array.filter(function (val) {
        return val.id === id;
    });
    //filter returns an array, and we just want the matching item
    return obj[0];
}
share|improve this answer

Use the filter method of jQuery:

 $(myArray).filter(function()
 {
     return this.id == desiredId;
 }).first();

That will return the first element with the specified Id.

It also has the benefit of a nice C# LINQ looking format.

share|improve this answer
2  
The filter method is intended for elements, not arrays. Use the grep method instead. – Guffa Sep 9 '11 at 15:56

You can get this easily using the map() function:

myArray = [{'id':'73','foo':'bar'},{'id':'45','foo':'bar'}];

var found = $.map(myArray, function(val) {
    return val.id == 45 ? val.foo : null;
});

//found[0] == "bar";

working example: http://jsfiddle.net/hunter/Pxaua/

share|improve this answer

A generic and more flexible version of the findById function above:

// array = [{key:value},{key:value}]
function objectFindByKey(array, key, value) {
    for (var i = 0; i < array.length; i++) {
        if (array[i][key] === value) {
            return array[i];
        }
    }
    return null;
}

var array = [{'id':'73','foo':'bar'},{'id':'45','foo':'bar'}];
var result_obj = objectFindByKey(array, 'id', '45');
share|improve this answer

You may try out Sugarjs from http://sugarjs.com/.

It has a very sweet .find method on Arrays. So you can find an element like this:

array.find( {id: 75} );

you may also pass an object with more properties to it to add another "where-clause"

Note that Sugarjs extends native objects, Some people consider this very evil...

share|improve this answer
var retObj ={};
$.each(ArrayOfObjects, function (index, obj) {

        if (obj.id === '5') { // but i have some issue here it is not   
                              // working for some reason number === "number" not working.
            retObj = obj;
        }
    });
return retObj;

It shoud return object by id.

share|improve this answer
There is some issue when obj.id is integer...it is not working 1 === "1" but i do not why...if u will do something like var idValue = '' + obj.id and then (idValue === id) it will be ok...hmm...do not know why it is so... – volumexxx 3 hours ago

Your Answer

 
or
required, but never shown
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.