Как сломать функцию _.each в underscore.js
Я ищу способ остановить итерации underscore.js _.each()
метод, но не могу найти решение. JQuery .each()
может сломаться, если вы делаете return false
,
Есть ли способ прекратить подчеркивать каждый ()?
_([1,2,3]).each(function(v){
if (v==2) return /*what?*/;
})
11 ответов
Вы не можете оторваться от each
метод - он эмулирует нативный forEach
поведение метода и родной forEach
не обеспечивает выхода из цикла (кроме создания исключения).
Однако все надежды не потеряны! Вы можете использовать Array.every
метод.:)
По этой ссылке:
every
выполняет предоставленноеcallback
Функция один раз для каждого элемента, присутствующего в массиве, пока не найдет тот, гдеcallback
возвращает ложное значение Если такой элемент найден,every
Метод сразу возвращает ложь.
Другими словами, вы можете сделать что-то запутанное, как это ( ссылка на JSFiddle):
[1, 2, 3, 4].every(function(n) {
alert(n);
return n !== 3;
});
Это предупредит 1
через 3
, а затем "вырваться" из цикла.
Вы используете underscore.js, поэтому вам будет приятно узнать, что он обеспечивает every
метод - они называют это every
, но, как упоминается в этой ссылке, они также предоставляют псевдоним all
,
Обновить:
_.find будет лучше, поскольку он выходит из цикла, когда элемент найден:
var searchArr = [{id:1,text:"foo"},{id:2,text:"bar"}];
var count = 0;
var filteredEl = _.find(searchArr,function(arrEl){
count = count +1;
if(arrEl.id === 1 ){
return arrEl;
}
});
console.log(filteredEl);
//since we are searching the first element in the array, the count will be one
console.log(count);
//output: filteredEl : {id:1,text:"foo"} , count: 1
** Старый **
Если вы хотите условно выйти из цикла, используйте _.filter api вместо _.each. Вот фрагмент кода
var searchArr = [{id:1,text:"foo"},{id:2,text:"bar"}];
var filteredEl = _.filter(searchArr,function(arrEl){
if(arrEl.id === 1 ){
return arrEl;
}
});
console.log(filteredEl);
//output: {id:1,text:"foo"}
Вы можете посмотреть на _.some
вместо _.each
,_.some
прекращает обход списка после того, как предикат верен. Результат (ы) могут быть сохранены во внешней переменной.
_.some([1, 2, 3], function(v) {
if (v == 2) return true;
})
Смотрите http://underscorejs.org/
Как и другие ответы, это невозможно. Вот комментарий о выключателе в подчеркивающей проблеме № 21
Может быть, вам нужен Underscore any() или find(), который прекратит обработку при выполнении условия.
Вы не можете сломать forEach
в подчеркивание, так как он имитирует родное поведение EcmaScript 5.
Я считаю, что если бы ваш массив был на самом деле объектом, вы могли бы вернуться, используя пустой объект.
_.({1,2,3,4,5}).each(function(v){
if(v===3) return {};
});
Также хорошо отметить, что каждый цикл не может быть разорван - для разрыва используйте вместо него _.find.
Обновить:
Вы можете "сломаться", выбросив ошибку внутрь и поймав ее снаружи: что-то вроде этого:
try{
_([1,2,3]).each(function(v){
if (v==2) throw new Error('break');
});
}catch(e){
if(e.message === 'break'){
//break successful
}
}
Это, очевидно, имеет некоторые последствия в отношении любых других исключений, которые ваш код вызывает в цикле, поэтому используйте его с осторожностью!
Работал в моем случае
var arr2 = _.filter(arr, function(item){
if ( item == 3 ) return item;
});