[JS] 6. 배열 (Array) & 이터레이터 (Iterator)
배열 (Array) : 순서가 있는 데이터 집합
- 배열의 각 요소 (
element)인 프로퍼티 리터럴을 인덱스 (프로퍼티 키)로 접근 length프로퍼티를 가지며, 배열의 길이보다 큰 접근은undefinedlength프로퍼티를 조정해 배열 길이를 조절할 수 있음 (-1 < length < 2^32)
- 자바스크립트에서 배열은 비균질적 (
Nonhomogeneous) : 고정 위치 및 크기를 가지지 않음- 희소 배열 (
sparse array) 자료 구조 : 검색에는 약하지만, 조작에는 우수!
- 희소 배열 (
// 3의 크기를 갖는 배열 생성
const arr1 = Array(3); // [ <3 empty items> ]
const arr2 = new Array(3); // [ <3 empty items> ]
const arr3 = [,,,]; // [ <3 empty items> ]
// 3의 크기를 갖고 1로 채워진 배열 생성
const arr4 = Array(3).fill(1); // [ 1,1,1 ]
// 3의 크기를 갖고 인덱스 1부터 1이 존재하는 배열 생성
const arr5 = Array(3).fill(1, 1); // [ <1 empty item>, 1, 1 ]
// 3의 크기를 갖고 인덱스 1 이상 2 미만에 1이 존재하는 배열 생성
const arr6 = Array(3).fill(1, 0, 2); // [ <1 empty item>, 1, <1 empty item> ]
// arr2를 복제한 유사 배열 객체 생성
const arr7 = Array.from(arr2); // [ undefined, undefined, undefined ]
// 3의 크기를 갖는 유사 배열 객체 생성
const arr8 = Array.from(Array(3)); // [ undefined, undefined, undefined ]
// 3의 크기를 갖고 1,2,3이 존재하는 유사 배열 객체 생성
const arr9 = Array.from(Array(3), (_, i) => i + 1); // [ 1, 2, 3 ]
// 3의 크기를 갖고 1,2,3이 존재하는 유사 배열 객체 생성
const arr10 = Array.from(Array(3).keys()); // [ 1, 2, 3 ]
// 3의 크기를 갖고 1로 채워진 배열 생성
const arr11 = [];
arr11.push(1); // [ 1 ]
arr11.push(1); // [ 1, 1 ]
arr11.push(1); // [ 1, 1, 1 ]
// 스택 배열
const stack = [];
stack.push(1);
stack.push(2);
stack.push(3);
stack.pop();
// 큐 배열
const queue = [];
queue.push(1);
queue.push(2);
queue.push(3);
queue.shift();
// 스택 배열, 큐 배열 초기화
stack.length = 0;
queue.length = 0;
// 배열 검색
const arr12 = [ 3, 7, 3, 9, 2];
arr12.indexOf(3); // 0
arr.lastIndexOf(3); // 2
arr.includes(3); // true
const arr13 = [ { id : 1 }, { id : 2 }, { id : 3 }, { id : 2 } ];
const idx = arr13.findIndex(item => item.id === 2); // 1
// 배열 루프
arr13.forEach(( arr, idx ) => console.log(arr.id));
// 배열 요소 합치기
const arr14 = arr1.concat(arr2);
const arr15 = [...arr1, ...arr2];
// 배열 평탄화
const arr16 = [ 1, 2, [3] ].flat();
console.log(arr16); // 1, 2, 3
const arr17 = [ 1, 2, [[3]] ].flat();
console.log(arr17); // 1, 2, [3]
const arr18 = [ 1, 2, [[3]] ].flat(2);
console.log(arr18); // 1, 2, 3
const arr = [1, 2, 3, 4, 5];
// ex1) [2,3]을 추출
const ex1 = arr.slice(1,3);
console.log(`\n#1`);
console.log(ex1);
// ex2) [3]부터 모두 다 추출
const ex2 = arr.slice(arr.indexOf(3));
console.log(`\n#2`);
console.log(ex2);
// ex3) [2,3,4] 제거하기
arr.splice(1, 3)
console.log(`\n#3`);
console.log(arr);
// ex4) 복원하기
arr.splice(1, 0, 2,3,4)
console.log(`\n#4`);
console.log(arr);
// ex5) [3] 부터 끝까지 제거하기
arr.splice(arr.indexOf(3))
console.log(`\n#5`);
console.log(arr);
// ex6) 복원하기
arr.splice(2, 0, 3,4,5)
console.log(`\n#6`);
console.log(arr);
// ex7) [1,2, 'X', 'Y', 'Z', 4, 5] 만들기
arr.splice(2, 1)
arr.splice(2, 0, 'X', 'Y', 'Z')
console.log(`\n#7`);
console.log(arr);
// ex8) 위 7번 문제를 splice를 사용하지 말고 작성하시오.
arr.splice(2, 3)
const ex8 = [...arr.slice(0, 2), 'X', 'Y', 'Z' , ...arr.slice(2)]
console.log(`\n#8`);
console.log(ex8);
리스트 (
List) : 중첩 참조link를 가진 객체const array = [1, 2, 3, …]; // 배열 const list = { // 리스트 value: 1, rest: { // 메모리 주소 (link) value: 2, rest: { value: 3, rest: {...} } } }→ 자비스크립트의
Array는List:List는 검색은 느리지만, 조작하는 것은 쉽다!
유사 배열 객체 (Array-like Object) : 배열과 유사한 형태를 갖지만, 배열은 아닌 객체
- 문자열,
Object,arguments,NodeList,JQuery객체 등 컬렉션 (Collection) 형태의 객체 데이터
Array.isArray(x) || x instanceof Array : false
- 인덱스는
0부터 시작해야 하며, 반드시length프로퍼티를 가짐 for ~ of등을 통해 순회 가능한iterable한 객체 (cf.iterator)forEach를 제외한 나머지 유사 배열 객체는Array메소드를 사용할 수 없음Array.from()으로 배열로 만들 수 있음
이터레이터 (Iterator) : next() 함수 호출 시 계속 그 다음 값을 반환하는 객체
- 현재 어디에 있고, 다음엔 어디로 가는지 아는 포인터 (
Pointer)- 이터러블 (
Iterable) 프로토콜 :Symbol.iterator를 구현 및 상속한 메소드를 호출하면, 이터레이터 반환 - 이터레이터 (
Iterator) 프로토콜 :next()를 호출하면,value(),done()을 가진 이터레이터 리터럴 반환
- 이터러블 (
class ItDog1 extends Dog {
[Symbol.iterator]() {
return this.name.split(', ').values();
}
}
const itDog1 = new ItDog1('Toby, Max, Sam');
console.log([...itDog1]);
class ItDog2 extends Dog {
[Symbol.iterator]() {
let idx = 0;
const names = this.name.split(/,\s?/);
return {
next() {
return { value: names[idx++],
done: idx > names.length };
}
};
}
}
const itDog2 = new ItDog2('Toby, Max, Sam');
for (const d of itDog2) console.log(d);
const iter = itDog2[Symbol.iterator]();
console.log(iter.next()); // 4회 반복
제너레이터 (Generator) : 제너레이터 함수 function*()의 실행을 제어하는 함수
- 실행 과정에서
yield를 만나면, 호출자 (caller)에게 정보 반환과 제어권을 넘김- 제너레이터를 호출하면 이터레이터를 얻음 → 실행이 한번에 끝나지 않는다!
function* route() { // function* ~ yield → iterator를 return하고, 일시정지(pause)한 상태로 시작!
const start = yield "출발 역은?"; // yield가 있으므로 caller에게 제어권을 넘긴다.
const end = yield "도착 역은?";
return `${start}역에서 출발하여 ${end}역에 도착합니다.`;
}
const caller = route();
caller.next();
caller.next('을지로입구');
caller.next('강남');