고전 for
for (let i = 0; i < arr.length; i++) {
// arr[i]
}
인덱스가 필요하거나 양끝에서 좁힐 때(투포인터) 필수입니다.
while
종료 조건이 데이터에 따라 달라질 때 (예: 큐가 빌 때까지).
while (lo <= hi) {
const mid = (lo + hi) >> 1;
// ...
}
무한 루프가 되지 않게 lo/hi가 반드시 변하는지 확인하세요. 브라우저는 Worker를 강제 종료할 수 있습니다.
for...of / for...in
for (const x of arr) { /* 값 */ }
for (const key of Object.keys(obj)) { /* 키 */ }
for...in은 배열 인덱스에도 쓰이지만 프로토타입 키가 섞일 수 있어 배열에는 for...of 또는 인덱스 for를 권합니다.
배열 고차 함수
arr.map((x) => x * 2);
arr.filter((x) => x > 0);
arr.reduce((acc, x) => acc + x, 0);
arr.some((x) => x === t);
arr.every((x) => x > 0);
arr.find((x) => x.id === id);
가독성이 좋을 때 쓰되, 중간에 break가 필요하면 일반 for가 낫습니다. reduce는 강력하지만 남발하면 읽기 어렵습니다. 합·곱·카운트에 먼저 익숙해지세요.
누적 초기값
- 합:
0 - 곱:
1 - 최댓값:
-Infinity또는arr[0](빈 배열 주의) - 최솟값:
Infinity또는arr[0]
오프바이원
i < n vs i <= n, 슬라이스 slice(0, k)는 끝 미포함.
손으로 작은 배열 하나를 적어 경계를 확인하는 습관이 오류를 줄입니다.
for vs while 선택
- 횟수가 명확 → for
- 조건이 데이터 의존 (이분 탐색, 큐) → while
중첩 루프와 복잡도
for (let i = 0; i < n; i++) {
for (let j = i + 1; j < n; j++) {
// O(n²) 쌍
}
}
n=1e5면 보통 불가. 해시·투포인터로 줄일 수 있는지 먼저 생각.
배열 메서드 함정
forEach는 break가 없습니다. 중간에 멈추면 for. map은 새 배열을 만듭니다. 부수 효과만 필요하면 for가 낫습니다.