[딥다이브] 27장 배열

주니·2023년 4월 11일
0

딥다이브

목록 보기
18/20

27. 배열

배열이란?

  • 여러 개의 값을 순차적으로 나열한 자료구조
    const arr = ['apple', 'banana', 'orange']
  • 배열이 가지고 있는 값을 요소(element)라고 한다. JS의 모든 값은 요소가 될 수 있다.
  • 자신의 위치를 나타내는 0 이상의 정수 인덱스를 갖는다.
  • length 프로퍼티를 갖는다. for문으로 순차적으로 접근 가능.
  • 객체 타입이다.
  • 일반 객체와 배열을 구분하는 가장 명확한 차이는 ‘값의 순서’와 ‘length 프로퍼티’이다.

JS 배열은 배열이 아니다.

JS배열은 자료구조에서 말하는 일반적인 의미의 배열과 다르다.

  • 각각의 메모리 공간은 동일한 크기를 갖지 않아도 되며
    연속적으로 이어져 있지 않을 수도 있다.
  • 이러한 배열을 희소 배열이라 한다. ↔ 밀집 배열
  • 일반적인 배열의 동작을 흉내낸 특수한 객체

일반적인 배열과 자바스크립트 배열의 장단점

  • 일반적인 배열은 인덱스로 요소에 빠르게 접근할 수 있다. 하지만 요소를 삽입 또는 삭제하는 경우 효율적이지 않다.
  • 자바스크립트 배열은 해시 테이블로 구현된 객체이므로 인덱스로 요소에 접근하는 경우 일반적인 배열보다 성능적인 면에서 느릴 수밖에 없는 구조적 단점이 있다. 하지만 요소를 삽입 또는 삭제하는 경우 일반적인 배열보다 빠른 성능을 기대할 수 있다.

JS엔진은 배열을 일반 객체와 구별하여 좀 더 배열처럼 동작하도록 최적화하여 구현함.

length 프로퍼티와 희소 배열

  • length 프로퍼티의 값은 배열에 요소를 추가하거나 삭제하면 자동 갱신된다.
  • 임의의 숫자 값을 명시적으로 할당할 수 있으며, 현재 길이보다 작은 숫자를 할당하면 길이가 줄어든다.
  • 희소 배열은 length와 배열 요소의 개수가 일치하지 않는다. length는 실제 요소 개수보다 언제나 크다.
  • 의도적으로 희소 배열을 만들어야 할 상황은 발생하지 않으며, 이를 사용하지 않도록 주의하자.
  • 배열에는 같은 타입의 요소를 연속적으로 위치시키는 것이 최선이다.

배열 생성

  • 배열 리터럴 const arr = [1,2,3]
  • Array 생성자 함수 const arr =new Array(10)
    • 전달된 인수가 1개이고 숫자인 경우 length 프로퍼티 값이 인수인 배열 생성
    • 전달된 인수가 2개 이상이거나 숫자가 아닌 경우 인수를 요소로 갖는 배열 생성
    • new 연산자와 함께 호출하지 않아도 생성. 이는 Array 생성자 함수 내부에서 new.target을 확인하기 때문
  • Array.of Array.of(1) 전달된 인수가 1개이고 숫자이더라도 인수를 요소로 갖는 배열 생성
  • Array.from 유사 배열 객체 또는 이터러블 객체를 인수로 전달받아 배열로 변환하여 반환.
    • Array.from(’hello’); // → [’h’,’e’,’l’,’l’,’o’]

배열 요소의 삭제

  • 배열은 사실 객체이기 때문에 delete연산자를 사용할 수 있다.
  • 객체의 프로퍼티를 삭제하므로, 희소 배열이 되며, length 프로퍼티 값은 변하지 않는다.
  • 따라서 delete는 사용하지 않는 것이 좋다.
  • 완전히 삭제하여 희소배열을 만들지 않기 위해 Array.prototype.splice 메서드를 사용!

배열 매서드

  • Array 생성자 함수는 정적 메서드를 제공하며, 배열 객체의 프로토타입인 Array.prototype은 프로토타입 메서드를 제공한다.
  • 원본 배열을 직접 변경하는 메서드는 외부 상태를 직접 변경하는 부수 효과가 있으므로 주의, 가급적 원본 배열을 직접 변경하지 않는 메서드 사용하기

Array.isArray : 전달된 인수가 배열이면 true, 아니면 false 반환

Array.prototype.indexOf : 원본 배열에서 인수로 전달된 요소를 검색하여 인덱스를 반환.
중복되는 요소가 여러 개 있으면 첫 번째 요소의 인덱스 반환, 존재하지 않으면 -1 반환.

Array.prototype.includes 메서드를 사용하면 가독성이 더 좋다.(ES7)

Array.prototype.push: 인수로 전달받은 모든 값을 원본 배열의 마지막 요소로 추가. lengh값 반환. 원본 배열을 직접 변경.

Array.prototype.pop : 마지막 요소를 제거하고 반환. 빈 배열이면 undefined 반환. 원본 배열 직접 변경

Array.prototype.unshift : 인수로 전달받은 모든 값을 배열의 선두에 요소로 추가. lengh값 반환. 원본 배열을 직접 변경. → 스프레드 문법을 사용하는 편이 좋음

Array.prototype.shift : 첫 번째 요소를 제거하고 반환. 빈 배열이면 undefined 반환. 원본 배열 직접 변경

Array.prototype.concat : 인수로 전달된 값들을 원본 배열의 마지막 요소로 추가한 새로운 배열 반환. 인수가 배열인 경우 배열을 해체하여 새 배열의 요소로 추가. 원본 배열 변경하지 않음. push와 unshift 메서드 대체 가능. 스프레드 문법으로 대체 가능.

💡 push/unshift 메서드와 concat 메서드 대신 ES6의 스프레드 문법을 일관성 있게 사용하자.

Array.prototype.splice : 중간에 요소를 추가하거나 중간 요소 제거. 원본 배열 직접 변경
3개의 매개변수 start(제거 시작 인덱스), deleteCount(start부터 제거할 요소 개수, 0일경우 제거하지 않고 새로운 요소 삽입), items(제거 위치에 삽입할 요소 목록, 생략 시 제거만).
filter메서드를 사용해 특정 요소 제거 가능.

Array.prototype.slice : 전달된 범위의 요소를 복사하여 배열로 반환. 원본 배열 변경 x.
2개의 매개변수 start(복사 시작), end(이전 범위까지 복사, 생략시 모든 요소 복사)

Array.prototype.join : 원본 배열의 모든 요소를 문자열로 변환한 후, 인수로 전달받은 문자열, 즉 구분자로 연결한 문자열을 반환. 구분자는 생략 가능, 기본은 ‘,’이다.

Array.prototype.reverse : 원본 배열의 순서를 반대로 뒤집어 반환. 원본 배열 변경.

Array.prototype.fill : 인수로 전달받은 값을 배열의 처음부터 끝 요소로 채운다. 원본 배열 변경.
두 번째 인수로 시작 인덱스, 세 번째 인수로 요소 채우기를 멈출 인덱스를 전달.

Array.prototype.includes : 배열 내 특정 요소가 포함되어 있는지 확인해 true/false 반환.
두 번째 인수로 검색 시작 인덱스 전달.

Array.prototype.flat : 인수로 전달한 깊이만큼 재귀적으로 배열을 평탄화. Infinity를 인수로 전달해 중첩 매열 모두를 평탄화 가능

💡 pop과 push 메서드로 스택을, shift와 push 메서드로 큐를 쉽게 구현할 수 있다.

배열 고차함수

  • 함수를 인수로 전달받거나 함수를 반환하는 함수
  • 불변성을 지향하는 함수형 프로그래밍에 기반을 둠

Array.prototype.sort : 배열의 모든 요소를 오름차순으로 정렬. 배열 직접 변경. 숫자 요소를 정렬할 때는 정렬 순서를 정의하는 비교 함수를 인수로 전달.

Array.prototype.forEach : 배열의 모든 요소를 순환하며 콜백 함수를 반복 호출. undefined반환. 원본 배열 변경x. for문에 비해 성능은 나쁘지만 가독성이 좋다.

Array.prototype.map : 자신을 호출한 배열의 모든 요소를 순회하면서 인수로 전달받은 콜백함수를 반복 호출. 콜백 함수의 반환값들로 구성된 새로운 배열 반환. 원본 배열 변경x

💡 forEach 메서드는 단순히 반복문을 대체하기 위한 고차 함수.
map 메서드는 요소값을 다른 값으로 매핑한 새로운 배열을 생성하기 위한 고차 함수.

Array.prototype.filter : 자신을 호출한 배열의 모든 요소를 순회하면서 인수로 전달받은 콜백함수를 반복 호출. 그리고 함수의 반환값이 true인 요소로만 구성된 새로운 배열 반환. 원본 배열 변경x

Array.prototype.reduce : 자신을 호출한 배열의 모든 요소를 순회하면서 인수로 전달받은 콜백함수를 반복 호출. 그리고 콜백 함수의 반환값을 다음 순회 시에 콜백 함수의 첫 번째 인수로 전달하면서 콜백 함수를 호출하여 하나의 결과값을 만들어 반환. 원본 배열 변경x. 첫 번째 인수로 콜백함수, 두 번째 인수로 초기값 전달. map, filter, some, every, find 같은 모든 배열의 고차 함수는 reduce 메서드로 구현 가능

Array.prototype.some : 자신을 호출한 배열의 모든 요소를 순회하면서 인수로 전달받은 콜백함수를 반복 호출. 이 때 반환값이 단 한 번이라도 참이면 true, 모두 거짓이면 false 반환.

Array.prototype.every : 자신을 호출한 배열의 모든 요소를 순회하면서 인수로 전달받은 콜백함수를 반복 호출. 이 때 반환값이 모두 참이면 true, 단 한 번이라도 false 반환.

Array.prototype.find : 자신을 호출한 배열의 모든 요소를 순회하면서 인수로 전달받은 콜백함수를 반복 호출하여 반환값이 true인 첫 번째 요소를 반환. 없으면 undefined 반환.

Array.prototype.findIndex : 자신을 호출한 배열의 모든 요소를 순회하면서 인수로 전달받은 콜백함수를 반복 호출하여 반환값이 true인 첫 번째 요소의 인덱스를 반환. 없으면 undefined 반환.

Array.prototype.flatMap : map과 flat 메서드를 순서대로 실행. 1단계만 평탄화.

0개의 댓글