Подтвердить что ты не робот

Как разбить функцию _.each в underscore.js

Я ищу способ остановить итерации метода underscore.js _.each(), но не могу найти решение. jQuery .each() может сломаться, если вы выполняете return false.

Есть ли способ остановить подчеркивание each()?

_([1,2,3]).each(function(v){
    if (v==2) return /*what?*/;
})
4b9b3361

Ответ 1

Вы не можете отказаться от метода each - он эмулирует поведение метода native forEach, а нативный forEach не обеспечивает выход из цикла (кроме исключения исключений).

Однако вся надежда не потеряна! Вы можете использовать метод Array.every.:)

Из этой ссылки:

every выполняет предоставленную функцию callback один раз для каждого элемента, присутствующего в массиве, до тех пор, пока не найдет ту, где callback возвращает ложное значение. Если такой элемент найден, метод every немедленно возвращает false.

Другими словами, вы можете сделать что-то свернутое таким образом (ссылка на JSFiddle):

[1, 2, 3, 4].every(function(n) {
    alert(n);
    return n !== 3;
});

Это предупредит 1 через 3, а затем "выйдет из строя" из цикла.

Вы используете underscore.js, поэтому вам будет приятно узнать, что он предоставляет метод every - они называют его every, но, как упоминается в этой ссылке, они также предоставляют псевдоним под названием all.

Ответ 2

Update:

_. 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"}

Ответ 3

Вы можете посмотреть _.some вместо _.each. _.some останавливает перемещение списка, как только предикат является истинным. Результат можно сохранить во внешней переменной.

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

См. http://underscorejs.org/#some

Ответ 4

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

Ответ 5

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

Ответ 6

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

Ответ 8

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

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

Ответ 9

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

http://underscorejs.org/#each

Ответ 10

Update:

На самом деле вы можете "сломать", выбросив ошибку внутри и поймав ее снаружи: примерно так:

try{
  _([1,2,3]).each(function(v){
    if (v==2) throw new Error('break');
  });
}catch(e){
  if(e.message === 'break'){
    //break successful
  }
}

Это, очевидно, имеет некоторые последствия в отношении любых других исключений, которые запускают ваш код в цикле, поэтому используйте с осторожностью!

Ответ 11

работал в моем случае

var arr2 = _.filter(arr, function(item){
    if ( item == 3 ) return item;
});