10

I want to get the index of the given value inside a Array using underscore.js.

Here is my case

var array = [{'id': 1, 'name': 'xxx'},
             {'id': 2, 'name': 'yyy'},
             {'id': 3, 'name': 'zzz'}];

var searchValue = {'id': 1, 'name': 'xxx'};

I used the following code,

var index = _.indexOf(array, function(data) { 
                alert(data.toSource()); //For testing purpose 
                return data === searchValue; 
            });

Also tried this too

var index = _.indexOf(array, {id: searchValue.id});

But it returns -1 . Since it does not enter into that function. So I didn't get that alert message.

Whats wrong with my code. Can anyone help me?

0

8 Answers 8

16

I'd strongly suggest taking a look at lodash. It contains quite a bit of nifty little functions that unfortunately underscore is lacking.

For example, this is what you would do with lodash:

var array = [{'id': 1, 'name': 'xxx'},
           {'id': 2, 'name': 'yyy'},
           {'id': 3, 'name': 'zzz'}];

var searchValue = {'id': 1, 'name': 'xxx'};


var index = _.findIndex(array, searchValue); 
console.log(index === 0); //-> true

http://lodash.com/docs#findIndex

Also, if you're bound to using Underscore - you can grab lodash's underscore build at https://raw.github.com/lodash/lodash/2.4.1/dist/lodash.underscore.js


ES2015

With ES2015 now in wide use (through transpilers like Babel), you could forego lodash and underscore for the task at hand and use native methods:

var arr = [{ id: 1 }, { id: 2}];

arr.findIndex(i => i.id === 1); // 0
Sign up to request clarification or add additional context in comments.

Comments

14

Use this instead:

var array = [{'id': 1, 'name': 'xxx'},
             {'id': 2, 'name': 'yyy'},
             {'id': 3, 'name': 'zzz'}];

var searchValue = {'id': 1, 'name': 'xxx'},
    index = -1;

_.each(array, function(data, idx) { 
   if (_.isEqual(data, searchValue)) {
      index = idx;
      return;
   }
});

console.log(index); //0

In your snippet data === searchValue compares the objects' references, you don't want to do this. On the other hand, if you use data == searchValue you are going to compare objects' string representations i.e. [Object object] if you don't have redefined toString methods.

So the correct way to compare the objects is to use _.isEqual.

2 Comments

@T.J.Crowder yep, agree. Fixed my answer.
You might want to review how isEqual is used. :-)
3

May be my suggestion will give you advice.

Why do you use callback for indexof method? The signature of indexof in underscore.js is the following:

_.indexOf(array, value, [isSorted]) 

find could be better for this task:

_.find(array, function(item, index) {
  if (item.id == searchValue.id) {
    alert(index);
  }
});

1 Comment

Interesting. The documentation of Underscore is lacking there, as they don't explain what are the arguments of the predicates (they only show examples with the value).
2

With objects, === and == check to see if two references refer to the same object; it doesn't check for equivalent objects:

var a = {foo: "bar"};
var b = {foo: "bar"};
console.log(a === b); // false, `a` and `b` refer to different (but equivalent) objects
a = b = {something: "here"};
console.log(a === b); // true, `a` and `b` refer to the *same* object

You have to test the object's properties to make the decision. In your case, the id property looks like a good option, or if you want to compare all of the properties, you might use Underscore's isEqual.

Comments

2

Underscore uses native indexOf method if available,else applies fallback. Thus, for a list of objects you have to implement it in some other way.

One example could be

_.chain(array).pluck("key").indexOf("value").value();

or

_.map(array,function(e) { return e.key; }).indexOf(value);

Comments

1

In case you have complicated objects, and want to search one object in the collection looking for a certain property, just go with:

 _.indexOf(arrayObj, _.findWhere(arrayObj, {id: 1})  );

Where "arrayObj" is the collection with objects, "id" is the prop, and "1" is the value being in search.

Comments

1

i am using find index

 _.findIndex(array, searchValue); 

Comments

0
_.find(array, function(item, index) {
  if (item.id == searchValue.id) {
    alert(index);
  }
});

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.