Как сломать функцию _.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/

_([1,2,3]).find(function(v){
    return v if (v==2);
})

Как и другие ответы, это невозможно. Вот комментарий о выключателе в подчеркивающей проблеме № 21

Может быть, вам нужен Underscore any() или find(), который прекратит обработку при выполнении условия.

Вы не можете сломать forEach в подчеркивание, так как он имитирует родное поведение EcmaScript 5.

Я считаю, что если бы ваш массив был на самом деле объектом, вы могли бы вернуться, используя пустой объект.

_.({1,2,3,4,5}).each(function(v){  
  if(v===3) return {}; 
});

Также хорошо отметить, что каждый цикл не может быть разорван - для разрыва используйте вместо него _.find.

http://underscorejs.org/

Обновить:

Вы можете "сломаться", выбросив ошибку внутрь и поймав ее снаружи: что-то вроде этого:

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;
});
Другие вопросы по тегам