[Info]Tags categorized posts and contents patterns..

[AJAX] Ajax Code E xamples.. [Book] About the book.. [CSS] CSS Code E xamples.. [DB] Sql Code E xamples.. [DEV] All development stor...

2016년 5월 9일 월요일

[JS] forEach에 break문 대신 some 사용하기..

출처 : Outsider's Dev Story https://blog.outsider.ne.kr/

프로그래밍 언어에는 컬렉션의 요소를 순회하는 forEach문이 존재한다. 자바스크립트에서는 forEach이고 자바에서 for이고 jQuery에서는 each이다. 언어마다 모양은 약간이 달라도 사용방법은 다 동일하다. forEach는 배열이나 객체의 모든 요소를 순회하는 함수인데 상황에 따라서는 모든 요소를 순회하지 않아도 될 때가 있다. 이럴때 사용하는 것이 break문인데 몇몇 언어에서는 break문을 제공하지 않고 있다. 예를 들어 자바스크립트에도 forEach문은 있지만 break문은 없고 스칼라에서도 2.8이 되어서야 break문이 추가되었다.

어떻게 break문이 없을 수 있는가 궁금하기도 했지만 (나도 잘 모르지만) 이는 약간 함수형 언어의 컨셉적인 부분으로 컬렉션을 순회하는 forEach문이 모두 순회하는 걸 당연하게 생각하고 있기 때문인것 같다. 컬렉션자체를 하나의 객체로 보고 객체를 다루는 메서드로 보고 절차적인 go to문과 비슷한 break문을 포함하지 않는 것같다.(그래도 많은 개발자들이 불평해서인지 대부분은 break문 혹은 return문으로 break의 역할을 할 수 있다. ) 홍민희님이 알려주셨는데 언어차원의 의도적인 결정은 아니고 미처 구현안한 것 뿐이랍니다. 

자바스크립트를 예로 들어보자.


1
2
3
4
5
JavaScript

[1,2,3,4,5].forEach(function(v) {
  if (v==2) console.log(v)
});

배열의 값이 2인 경우만 출력하도록 한 것으로 이렇게 배열중 일부값을 찾아서 뭔가를 수행하고자 하는 것이다. 위 예제는 잘 동작하지만 사실 이 예제는 2를 출력한 후에도 불필요하게 3,4,5도 순회하게 되기 때문에 여기서 성능을 위해서 break문으로 불필요한 순회를 없애고 싶어진다.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
JavaScript

var Break = new Error('Break');

try {
  [1,2,3,4,5].forEach(function(v) {
    if (v==2) {
      console.log('v: ', v)
      throw Break;
    }
  });
} catch (e) {
  if (e!= Break) throw Break; 
}

자바스크립트의 경우 break문이 없기 때문에 위처럼 Break라는 커스톰 오류객체를 정의해서 순회하다가 멈춰하 하는 곳에서 예외를 던져서 순회를 멈출 수 있다. 이는 try-catch를 교묘히 이용해서 원하는 동작을 하도록 한 것이지만 코드에서 보듯이 원하는 것에 비해서 코드가 너무 지저분해져서 가독성도 그다지 좋지 않다.

여기서 forEach에 break 조합대신 사용할 수 있는 것이 some()이다. some은 컬렉션의 요소 중 최소 1개라도 조건을 만족시키는지 검사하는 메서드이고 언어에 따라 some이 아닌 경우도 있지만 비슷한 기능을 하는 언어는 존재한다.(스칼라의 경우에는 exists이다.) 위에서 작성한 예제와 똑같은 함수를 some()를 사용해서 다음과 같이 작성할 수 있다.


1
2
3
4
5
6
JavaScript

[1,2,3,4,5].some(function(v) {
   if(v == 2) console.log(v);
   return (v ==2);
});

some()은 조건이 true가 되는 순간 순회를 멈추기 때문에 우리가 원하는 동작을 충족시킬 수 있다. 억지로 break문을 사용하는 것보다는 훨씬 소스도 깔끔해 졌고 함수의 용도에도 맞아보인다.

댓글 없음:

댓글 쓰기