underscore.js에서 _.each 함수를 중단하는 방법


200

underscore.js _.each()메서드의 반복을 중지하는 방법을 찾고 있지만 솔루션을 찾을 수 없습니다. .each()그렇게하면 jQuery 가 중단 될 수 있습니다 return false.

각 밑줄을 멈추는 방법이 있습니까?

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

4
네이티브 forEach함수는이 기능을 제공하지 않기 때문에 가능하지 않다고 생각 합니다.
Felix Kling

8
일반적으로 each클로저 (대부분의 언어)와 함께 사용할 경우 목록을 먼저 필터링하려고합니다. 그렇게하면 침입으로부터 걱정할 필요가 없습니다. 일반적으로 반복에서 조기에 중단해야하는 경우에는 다른 방법이있을 수 있습니다.
Rob Hruska

다음은 Groovy에 대한 몇 가지 관련 질문이며, 동작 ( each클로저 에서 편리하게 벗어날 수 없음 )이 JavaScript와 유사합니다.
Rob Hruska

다른 사람들이 지적했듯이 @Dmitry_F는 원하는 것을 정확하게 수행 할 수 없습니다. 그러나 내가 설명 Array.every했듯이 원하는 동작을 에뮬레이트하는 데 사용할 수 있습니다 .
aeskr

@ 롭. 건배. 첫 번째 의견은 정말 도움이되었습니다. 실제로 내가 할 수있는 다른 방법이있었습니다.
net.uk.sweet

답변:


267

each메서드 에서 벗어날 수 없습니다 . 네이티브 forEach메서드의 동작을 에뮬레이트하고 네이티브 forEach는 예외를 제외하고 루프를 이스케이프 처리하지 않습니다.

그러나 모든 희망이 사라지지는 않습니다! Array.every방법을 사용할 수 있습니다 . :)

그 링크에서 :

everyfalse 값을 반환하는 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
underscore.js가 이것에 대한 구현을 제공합니까?
Felix Kling

1
@FelixKling, 그렇습니다. 나는 그것을 내 대답에 추가했습니다.
aeskr

2
현재 (2013 년 5 월), 밑줄로 배열을위한 방법 _.every()이나 _.all()방법이 없으므로-을 고수하십시오 Array.every().
pkyeck

3
이것은 작동하지만을 사용하는 일반적인 이유입니다 every. 따라서 가독성에주의하십시오.
evanrmurphy

3
밑줄 문서 _.each()에는 루프에서 벗어날 수 없다는 사실에 대한 메모가 있으며 _.find()대신 사용 하는 것이 좋습니다 . http://underscorejs.org/#each
blatt

70

최신 정보:

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

** 낡은 **

조건부로 루프를 해제하려면 _.each 대신 _.filter api를 사용하십시오. 다음은 코드 스 니펫입니다.

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

1
이것은 루프를 끊지 않고 배열 만 필터링합니다. 배열에 2 개가 아닌 20.000 개의 항목이 있다고 상상해보십시오. 당신은 당신이 게시 한 예제 만 출력하지만 루프는 20.000 번 실행됩니다 :(
pkyeck

@pkyeck 맞습니다. elemnt를 찾은 후 중단되므로 _.find가 _.filter보다 낫습니다. 여기 바이올린이 있습니다 : jsfiddle.net/niki4810/9K3EV
Nikhil

2
이 답변이 올바른 것으로 표시되어야한다고 생각합니다. _.find요청 된 내용을 정확하게 수행합니다 true. 콜백이 반환 될 때까지 목록을 반복합니다 .
Fabien Quatravaux

허용 된 답변 (Array.every)은 객체에서 작동하지 않지만 _.find ()는 작동하기 때문에이 답변에 투표했습니다.
matt

그리고 그것은 문서에서 권장하는 것입니다 : 또한 각 루프가 끊어 질 수 없다는 점에 주목하는 것이 좋습니다. 깨 뜨리려면 대신 _.find를 사용하십시오.
shaharsol 2016 년

15

_.some대신에 살펴볼 수 있습니다 _.each. _.some술어가 true이면 목록 순회를 중지합니다. 결과는 외부 변수에 저장 될 수 있습니다.

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

http://underscorejs.org/#some 참조



3

Underscore의 any () 또는 find ()를 원할 수도 있습니다. 조건이 충족되면 처리가 중지됩니다.



3

forEach밑줄은 EcmaScript 5 기본 동작을 에뮬레이트하므로 밑줄로 구분할 수 없습니다 .


2

배열이 실제로 객체 인 경우 빈 객체를 사용하여 반환 할 수 있다고 생각합니다.

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

forEach에 대해 제공된 대안에서 빈 오브젝트를 리턴하는지 여부를 확인하기 위해 밑줄에서 수행하는 비교는 기본 오브젝트를 사용할 수없는 경우에만 수행되므로 EcmaScript v <5에서만 발생합니다.
Alfonso de la Osa


1

최신 정보:

당신은 실제로 내부에 오류를 던지고 외부에서 잡아 냄으로써 "파손"할 수 있습니다.

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

이것은 분명히 루프에서 코드가 트리거하는 다른 예외와 관련이 있으므로 신중하게 사용하십시오!


사랑 나는 이것에 대한 많은 다운 표를 얻고,이 사람은 자신에 대한 업의 전체 부하 얻는 방법 stackoverflow.com/a/2641374/674720
bm_i

1
나는 파티에 늦었지만 녀석은 당신이 제안한 것을 말했을뿐만 아니라 두 가지 대안을 더 제공했습니다. 사용자가 원하는 경우 "해킹"만 제공됩니다. 대신 당신은 못생긴 핵을 제공했습니다.
Areks

0

내 경우에는 일했다

var arr2 = _.filter(arr, function(item){
    if ( item == 3 ) return item;
});
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.