可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
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?
回答1:
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:
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
回答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);
}
});
回答4:
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
.
回答5:
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);
回答6:
_.find(array, function(item, index) {
if (item.id == searchValue.id) {
alert(index);
}
});
回答7:
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.