배열 메서드와 배열 고차 함수

se-een·2022년 9월 24일
0
post-thumbnail

이 글은 '이웅모'님의 '모던 자바스크립트 Deep Dive' 책을 통해 공부한 내용을 정리한 글입니다. 저작권 보호를 위해 책의 내용은 요약되었습니다.

배열

배열은 객체타입이다. 프로토타입으로 Array.prototype을 가지며 모든 프로토타입 객체의 프로토타입 말단은 Object.prototype 이기에 일반 객체보다 값에 순차적으로 접근하기 적합한 자료구조이다.

또한 일반적인 배열의 방식인 밀집 배열(Dense Array)와는 다르게 희소 배열(Sparse Array) 방식이다. 즉, 연속적으로 이어져 있지 않을 수도 있으며 각각의 메모리 공간 또한 동일한 크기를 갖지 않을 수도 있다. 이는 배열의 접근에는 밀집 배열 대비 불리하지만 수정에는 유리하다. 희소 배열의 특징으로 실제 배열의 크기보다 해당 배열의 length 프로퍼티 값을 더 크게 할당할 수는 있지만 실제 배열의 크기가 늘어나지는 않는다.

// 희소배열과 length 프로퍼티

const arr = [1];

arr.length = 5;

console.log(arr.length); // 5
console.log(arr); // [1, 비어 있음 × 4]

배열 생성 방식

1. 배열 리터럴

const arr = [1,2,3];
console.log(arr); // (3) [1,2,3]

2. Array 생성자 함수

// 인수의 개수에 따라 다르게 동작한다.

const arr1 = new Array(5);
console.log(arr1); // (5) [비어 있음 × 5]

const arr2 = new Array(1,2,3,4,5);
console.log(arr2); // (5) [1, 2, 3, 4, 5]

const arr3 = Array(1,2,3); // new.target 통해 new Array(1,2,3)으로 동작
console.log(arr3); // (3) [1, 2, 3]

3. Array.of

// ES6 도입, 인수가 한 개라도 해당 인수로 배열 생성

const arr1 = Array.of(1);
console.log(arr1); // [1]

const arr2 = Array.of("str", "num");
console.log(arr2); // (2) ['str', 'num']

4. Array.from

// ES6 도입, 유사 배열 객체 또는 이터러블 객체를 배열로 변환

const obj = { length : 2, 0 : "zero", 1 : "one" };

const arr1 = Array.from(obj);
console.log(arr1); // (2) ['zero', 'one']

const arr2 = Array.from("abcd");
console.log(arr2); // (4) ['a', 'b', 'c', 'd']

배열 메서드

Array 생성자 함수는 정적 메서드를, Array.prototype은 프로토타입 메서드를 제공한다.

1. Array.isArray

  • 기능 : 인수가 배열인지 판단한다.
  • 반환 : true 또는 false
Array.isArray([]); // true
Array.isArray({}); // false

2. Array.prototype.indexOf

  • 기능 : 인수의 인덱스 위치를 알아낸다.
  • 반환 : 인수의 첫번째 인덱스 값 또는 -1
const arr = [1,1,2,4];

// 첫 번째 인수 : 인덱스를 검색할 값
// 두 번째 인수 : 시작할 인덱스 값
arr.indexOf(1); // 0
arr.indexOf(3); // -1
arr.indexOf(1,1); // 1

3. Array.prototype.push

  • 기능 : 인수를 원본 배열의 마지막 요소로 추가한다.
  • 반환 : 변경된 배열의 길이
const arr = [1,2,3];

arr.push(4, 5); // 5
console.log(arr); // (5) [1, 2, 3, 4, 5]

4. Array.prototype.pop

  • 기능 : 원본 배열의 마지막 요소를 제거한다.
  • 반환 : 제거한 요소 값 또는 undefined
const arr = [1,2,3];

arr.pop(); // 3
console.log(arr) // (2) [1, 2]

5. Array.prototype.shift

  • 기능 : 원본 배열의 첫번째 요소를 가져오고 제거한다.
  • 반환 : 제거된 요소 값 또는 undefined
const arr = [1,2,3];

arr.shift(); // 1
console.log(arr); // (2) [2, 3]

6. Array.prototype.unshift

  • 기능 : 인수를 원본 배열의 첫 번째 요소로 추가한다.
  • 반환 : 변경된 배열의 길이
const arr = [1,2,3];

arr.unshift(4,5); // 5
console.log(arr); // (5) [4, 5, 1, 2, 3]

7. Array.prototype.concat

  • 기능 : 인수를 배열의 마지막 요소로 추가한다.
  • 반환 : 변경된 새로운 배열
  • push와 차이 : 원본 배열 수정 유무
const arrA = [1,2];
const arrB = [3,4];

arrA.concat(arrB, 5); // (5) [1, 2, 3, 4, 5]
// arrB.unshift(1,2)와 기능은 동일
[1,2].concat(arrB); // (4) [1, 2, 3, 4]

console.log(arrA); // (2) [1, 2]

8. Array.prototype.slice

  • 기능 : 인수의 범위를 기준으로 배열을 복사한다. (얕은 복사)
  • 반환 : 복사된 새로운 배열
const arr = [1,2,3,4,5];

arr.slice(); // (5) [1, 2, 3, 4, 5]
arr.slice(0,3); // (3) [1, 2, 3]
arr.slice(-2); // (2) [4, 5]

console.log(arr === arr.slice()); // false

9. Array.prototype.splice

  • 기능 : 인수의 범위를 기준으로 원본 배열을 수정한다.
  • 반환 : 제거된 요소(들)의 배열 또는 빈 배열
const arr = [1,2,3];

// 첫 번째 인수 : 시작할 인덱스 값
// 두 번째 인수 : 제거할 요소의 개수
// 세 번째~ 인수 : 제거된 요소의 위치에 새롭게 추가할 요소
arr.splice(0, 2, 10, 20); // (2) [1, 2]
console.log(arr) // (3) [10, 20, 3]

10. Array.prototype.join

  • 기능 : 배열을 인수로 연결한 문자열로 반환한다.
  • 반환 : 인수(구분자)가 포함된 문자열
const arr = ["h","e","l","l","o"];

arr.join(); // "h,e,l,l,o"
arr.join(""); // "hello"
arr.join("\n"); 
// h
// e
// l
// l
// o

11. Array.prototype.reverse

  • 기능 : 원본 배열의 순서를 반대로 뒤집는다.
  • 반환 : 변경된(뒤집힌) 원본 배열
const arr = [1,2,3];

arr.reverse(); // (3) [3, 2, 1]
console.log(arr); // (3) [3, 2, 1]

12. Array.prototype.fill

  • 기능 : 인수를 원본 배열의 모든 요소로 채운다.
  • 반환 : 변경된 원본 배열
const arr = [1,2,3];

// 첫 번째 인수 : 채울 값
// 두 번째 인수 : 시작할 인덱스 값
// 세 번째 인수 : 마칠 인덱스 값(미포함)
arr.fill(0); // (3) [0, 0, 0]
arr.fill(5,0,2) // (3) [5, 5, 0]
// Array 생성자 함수로 생성한 배열의 초기 값 설정

const arr = new Array(3).fill(0);

console.log(arr); // (3) [0, 0, 0]

13. Array.prototype.includes

  • 기능 : 배열 내 인수가 포함되어 있는지 확인한다.
  • 반환 : true 또는 false
  • indexOf와 차이 : 반환 값, NaN 포함 여부
const arr = [1,2,3];

// 첫 번째 인수 : 검색할 값
// 두 번째 인수 : 시작할 인덱스 값
arr.includes(1); // true
arr.includes(5); // false
arr.includes(1, 1); // false

[NaN].indexOf(NaN) !== -1; // false
[NaN].includes(NaN); // true

14. Array.prototype.flat

  • 기능 : 인수의 값만큼 배열을 재귀적으로 평탄화한다.
  • 반환 : 변경된(평탄화된) 원본 배열
const arrA = [1,[2,3,[4,5]]];
const arrB = [1,[2,[3,[4]]]];

arrA.flat(); // (4) [1, 2, 3, [4, 5]]
// arrB.flat().flat()과 동일
arrB.flat(2); // (4) [1, 2, 3, [4]]

배열 고차 함수

고차함수는 외부 상태의 변경, 가변 데이터를 지양하고 불변성을 지향하는 함수형 프로그래밍에 기반한다. 함수형 프로그래밍은 가독성 및 조건문, 반복문을 제거하여 복잡성을 해결하고 변수 사용을 억제하여 상태 변경을 피하려는 프로그래밍 패러다임이다.

1. Array.prototype.sort

  • 기능 : 유니코드 코드 포인트의 순으로 정렬한다.
  • 반환 : 정렬된 원본 배열
  • 주의 : break, continue 사용 불가
const arr1 = ["B", "C", "A"];
const arr2 = [10, 1, 2];

arr1.sort() // (3) ['A', 'B', 'C']
arr2.sort() // (3) [1, 10, 2]

문자는 상관 없지만 숫자의 경우 유니코드 순으로 정렬되다보니 예상한 1,2,10의 순이 아닌 1,10,2임을 확인할 수 있다. 따라서 정렬 순서를 정의하는 비교 함수를 인수로 전달할 필요가 있다.

비교 함수의 반환값이

  • 0보다 작으면 : 첫 번째 인수를 우선하여 정렬
  • 0이면 : 정렬하지 않음 (JS 엔진마다 다르게 동작할 수도 있다.)
  • 0보다 크면 : 두 번째 인수를 우선하여 정렬
const arr2 = [10, 1, 2];

arr2.sort((a,b)=>a-b); // (3) [1, 2, 10] 오름차순
arr2.sort((a,b)=>b-a); // (3) [10, 2, 1] 내림차순

2. Array.prototype.forEach

  • 기능 : 호출한 배열을 순회하며 콜백 함수에 처리 요소를 부여해 반복 호출한다. (for 대용)
  • 반환 : undefined
  • 주의 : break, continue 사용 불가 / 희소배열의 empty 값은 순회 대상에서 제외
const arr = [1,2,3];
const res = [];

// 첫 번째 인수 : 배열의 요소값
// 두 번째 인수 : 배열의 인덱스
// 세 번째 인수 : 호출한 배열(this)
arr.forEach((item, idx, arr) => {
  res[idx]=item**2;
  console.log("this : " + JSON.stringify(arr)); // this : [1, 2, 3]
});

// 위 구문과 기능은 동일
arr.forEach((i)=>res.push(i**2));

console.log(res); // (3) [1, 4, 9]

3. Array.prototype.map

  • 기능 : 원본 배열을 변경하지 않고 콜백 함수의 반환값들로 구성된 새로운 배열을 반환한다.
  • 반환 : 콜백 함수의 반환값들의 배열
  • 주의 : break, continue 사용 불가 / 희소배열의 empty 값은 순회 대상에서 제외
const arr = [1,2,3];

// 첫 번째 인수 : 배열의 요소값
// 두 번째 인수 : 배열의 인덱스
// 세 번째 인수 : 호출한 배열(this)
const res1 = arr.map((item, idx, arr) => {
  console.log("this : " + JSON.stringify(arr)); // this : [1, 2, 3]
  return item**2;
});

// 위 구문과 기능은 동일
const res2 = arr.map((i)=>i**2);

console.log(res1, res2); // (3) [1, 4, 9] (3) [1, 4, 9]

4. Array.prototype.filter

  • 기능 : 원본 배열은 변경하지 않고 콜백 함수의 반환값이 true인 요소로만 새로운 배열을 반환한다.
  • 반환 : 콜백 함수의 반환값 중 true인 요소의 배열
  • 주의 : break, continue 사용 불가 / 희소배열의 empty 값은 순회 대상에서 제외
const arr = [1,2,3,4,5];

// 첫 번째 인수 : 배열의 요소값
// 두 번째 인수 : 배열의 인덱스
// 세 번째 인수 : 호출한 배열(this)
const res1 = arr.filter((item, idx, arr) => {
  console.log("this : " + JSON.stringify(arr)); // this : [1, 2, 3, 4, 5]
  return item % 2;
});

// 위 구문과 기능은 동일
const res2 = arr.filter((i)=>i%2);

console.log(res1, res2) // (3) [1, 3, 5] (3) [1, 3, 5]

5. Array.prototype.reduce

  • 기능 : 원본 배열은 변경하지 않고 콜백 함수의 반환값을 다음 순회시에 콜백 함수의 첫 번째 인수로 전달하는 과정을 반복하여 하나의 결과값을 만든다.
  • 반환 : 결과값
  • 주의 : break, continue 사용 불가 / 희소배열의 empty 값은 순회 대상에서 제외
const arr = [1,2,3,4];

// reduce 함수 인수
// 첫 번째 인수 : 콜백 함수
// 두 번째 인수 : 초기값

// 콜백 함수 인수
// 첫 번째 인수 : 이전값 또는 초기값
// 두 번째 인수 : 현재값
// 세 번째 인수 : 배열의 인덱스
// 네 번째 인수 : 호출한 배열(this)
const res1 = arr.reduce((pre, cur, idx, arr) => {
  console.log("this : " + JSON.stringify(arr)); // this : [1, 2, 3, 4]
  return pre + cur;
}, 0);

// 위 구문과 기능은 동일
const res2 = arr.reduce((pre, cur)=>pre + cur, 0);

console.log(res1, res2) // 10 10

6. Array.prototype.some

  • 기능 : 콜백 함수의 반환값이 단 한 번이라도 참이면 true, 모두 거짓이면 false를 반환한다. (OR 연산)
  • 반환 : true 또는 false
  • 주의 : break, continue 사용 불가
const arr = [1,2,3,4];

arr.some(i => i>3); // true

7. Array.prototype.every

  • 기능 : 콜백 함수의 반환값이 단 한 번이라도 거짓이면 false, 모두 참이면 true를 반환한다. (AND 연산)
  • 반환 : true 또는 false
  • 주의 : break, continue 사용 불가
const arr = [1,2,3,4];

arr.every(i => i>3); // false

8. Array.prototype.find

  • 기능 : 콜백 함수의 반환값이 true인 첫 번째 요소를 반환한다.
  • 반환 : 요소 또는 undefined
  • 주의 : break, continue 사용 불가
const arr = [
  {id : 1, alphabet : "A"},
  {id : 2, alphabet : "B"}
];

arr.find(i=>i.id===1) // {id: 1, alphabet: 'A'}

9. Array.prototype.findIndex

  • 기능 : 콜백 함수의 반환값이 true인 첫 번째 요소의 인덱스를 반환한다.
  • 반환 : 요소의 인덱스 값 또는 undefined
  • 주의 : break, continue 사용 불가
const arr = [
  {id : 1, alphabet : "A"},
  {id : 2, alphabet : "B"}
];

arr.findIndex(i=>i.id===1) // 0
profile
woowacourse 5th FE

0개의 댓글