findIndex was added in 1.8:
index = _.findIndex(tv, function(voteItem) { return voteItem.id == voteID })
See: http://underscorejs.org/#findIndex
Alternatively, this also works, if you don't mind making another temporary list:
index = _.indexOf(_.pluck(tv, 'id'), voteId);
See: http://underscorejs.org/#pluck
Answer from Ropez on Stack OverflowfindIndex was added in 1.8:
index = _.findIndex(tv, function(voteItem) { return voteItem.id == voteID })
See: http://underscorejs.org/#findIndex
Alternatively, this also works, if you don't mind making another temporary list:
index = _.indexOf(_.pluck(tv, 'id'), voteId);
See: http://underscorejs.org/#pluck
Lo-Dash, which extends Underscore, has findIndex method, that can find the index of a given instance, or by a given predicate, or according to the properties of a given object.
In your case, I would do:
var index = _.findIndex(tv, { id: voteID });
Give it a try.
You can achieve the same goal with pure JS. You don't need lodash
const data = [{
booleanProperty: false
},
{
booleanProperty: true
},
{
booleanProperty: false
},
{
booleanProperty: true
},
{
booleanProperty: false
}
];
const indexItems = data.map((item, index) => item.booleanProperty === true ? index : null).filter((item) => item !== null);
console.log(indexItems)
If you need a single index satisfying that condition, you can use findIndex of es6 or lodash
data.findIndex(a=>a.booleanProperty)
If you need all the indexes satisfying your condition, you can either map and filter together sequentially (as shown in ben's answer) or you can merge them to a single reduce to iterate only once and build your index array. here we go:
data.reduce((r, a, i)=> (a.booleanProperty && r.push(i), r), [])
let data = [{"booleanProperty":false},{"booleanProperty":true},{"booleanProperty":false},{"booleanProperty":true},{"booleanProperty":false}];
let indexes = data.reduce((r, a, i)=> (a.booleanProperty && r.push(i), r), []);
console.log(indexes);
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
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.
From the Lodash documentation:
Iterates over elements of
collectionand invokesiterateefor each element. Theiterateeis invoked with three arguments:(value, index|key, collection). Iteratee functions may exit iteration early by explicitly returningfalse.
This means that you can simply do:
_.each( days, function( day, i ){
});
So your whole code becomes:
var days = [5, 15, 25];
var hours = [6, 8, 7];
var result = [];
_.each( days, function( day, i ){
if( days[i] < a && b < days[i+1] ){ // days[i] == day
result.push( hours[i] );
} else if( days[i] > a && days[i] < b ){
result.push( hours[i] );
if( i > 0 ){
result.push( hours[i-1] );
}
}
})
Here is a jsFiddle to experiment.
From Lodash Documentation:
Iterates over elements of collection and invokes iteratee for each element. The iteratee is invoked with three arguments: (value, index|key, collection). Iteratee functions may exit iteration early by explicitly returning false.
_.each gets only one Collection to iterate as the first argument, and a function "iteratee" for the second argument.
So, for is a good option for you.
However, if you still want to use lodash you can get help from _range to create an array of indices, and then you can do something like that:
(in javascript of course)
let days = [5, 15, 25];
let hours = [6, 8, 7];
let result = [];
_.each(_.range(days.length),function(i) {
if (days[i] < a && b < days[i+1]) {
result.push(hours[i]);
} else if (days[i] > a && days[i] < b) {
result.push(hours[i]);
if (i > 0) {
result.push(hours[i-1]);
}
}
});