javaScript/js.array1

배열

1. 배열이란?

  • 배열은 여러 개의 값을 순차적으로 나열한 자료 구조이다.
  • 배열이 가지고 있는 값을 요소(element)라 한다.
  • 자바스크립트에서 값으로 인정하는 모든 것은 배열의 요소가 된다.
  • 배열의 요소는 배열에서 자신의 위치를 나타내는 0 이상의 정수인 index를 갖는다. 이를 통해 요소에 접근할 수 있다.
  • 배열은 요소의 개수, 즉 배열의 길이를 나타내는 length 프로퍼티를 갖는다.
  • 배열 리터럴 또는 Array 생성자 함수로 생성할 수 있다.
    배열의 생성자 함수는 Array이며 배열의 프로토타입 객체는 Array.prototype. -> 배열을 위한 빌트인 메소드 들을 제공한다.
  • 배열은 객체이다. 일반 객체와는 다른 특징
구분 객체 배열
구조 프로퍼티 키와 프로퍼티 값 인덱스와 요소
값의 참조 프로퍼티 키 인덱스
값의 순서 X O
length프로퍼티 X O

2. 자바스크립트의 배열

희소 배열(sparse array) (자바스크립트)
배열의 요소가 연속적으로 이어져 있지 않는 배열

밀집 배열 (Dense array)

  • 일반적인 배열로 하나의 타입으로 통일되어 있으면서 서로 연속적으로 인접해 있다.

  • 매우 효율적이며 고속으로 동작한다.

  • 배열에 요소를 삽입하거나 삭제하는 경우, 배열 요소를 연속적으로 유지하기 위해 요소를 이동시켜야 하는 단점

  • 자바스크립트는 일반적인 배열의 동작을 흉내낸 특수한 객체이다.

  • 인덱스를 프로퍼티 키로 갖으며 length 프로퍼티를 갖는 특수한 객체이다.

  • 어떤 타입의 값이라도 배열의 요소가 될 수 있다.

  • 해시 테이블로 구현된 객체이므로 인덱스로 배열 요소에 접근하는 경우, 일반적인 배열보다 성능적인 면에서 느릴수 밖에 없는 구조적 단점

  • 특정 요소를 탐색하거나 추가, 삭제하는 경우에는 일반적인 배열보다 빠른 성능

    3. length 프로퍼티와 희소 배열

  • length 프로퍼티는 요소의 개수, 즉 배열의 길이를 나타내는 정수를 값으로 갖는다.

  • length 프로퍼티의 값은 빈 배열일 경우 0이며, 빈 배열이 아닐 경우 가장 큰 인덱스에 +1 이다.

    1
    2
    [].length  //0
    [1, 2, 3].length // 3
  • length 프로퍼티의 값은 배열에 요소를 추가하거나 삭제하면 자동 갱신된다.

  • length 프로퍼티의 값은 임의의 숫자 값을 명시적으로 할당할 수도 있다.

    • length 프로퍼티 값보다 작은 숫자 값을 할당하면 배열의 길이가 줄어든다.
    • 큰 숫자 값을 할당하는 경우, 프로퍼티 값은 변경되지만 실제로 배열의 길이가 늘어나지 않는다.
    • 값 없이 비어있는 요소를 위해 메모리 공간을 확보하지 않으며 빈 요소를 생성하지 않는다.
      1
      2
      3
      4
      const arr = [1, 2];
      arr.length = 4;
      console.log(arr.length); // 4;
      console.log(arr); [ 1, 2, empty x 2]; //empty는 실제로 추가된 배열의 요소가 아니다.
      이처럼 배열의 요소가 연속적으로 위치하지 않고 일부가 비어있는 배열을 희소 배열이라 한다.
      희소 배열의 length는 배열의 실제 요소 개수보다 언제나 크다.
      1
      2
      3
      4
      5
      const sparse = [, 2, , 4];  //희소 배열
      console.log(sparse.length); //4
      console.log(sparse); // [empty, 2, empty, 4]

      // 배열 sparse에는 인덱스 0, 2인 요소가 존재하지 않는다.
      자바스크립트에서 허용하더라도, 희소 배열은 사용하지 않는 것이 좋다.

4. 배열 생성

4.1 배열 리터럴

  • 0개 이상의 요소를 쉼표로 구분하여 대괄호를 묶는다. 프로퍼티 이름이 없고 값만 존재한다.
  • 존재하지않는 요소(프로퍼티 키)를 참조할 경우 undifined를 반환한다.

4.2 Array 생성자 함수

  • Array 생성자 함수를 통해 배열을 생성할 수 있다.
  • Array 생성자 함수는 전달된 인수 개수에 따라 다르게 동작한다.
    • 전달된 인수가 1개이고 숫자인 경우, 인수를 length 프로퍼티의 값으로 갖는 배열을 생성한다.
      1
      2
      3
      const arr = new Array(10);
      const.log(arr); // [empty x 10]
      const.log(arr.length); // 10
    • 전달된 인수가 없는 경우, 빈 배열을 생성한다. []
    • 전달된 인수가 2개 이상이거나 숫자가 아닌 경우, 인수를 요소로 갖는 배열을 생성한다.
  • new 연산자와 함께 호출하지 않아도 배열을 생성하는 생성자 함수로 동작한다.
    Array 생성자 함수 내부에서 new.target을 확인하기 때문이다.

4.3 Array.of

  • ES6에서 도입. 전달된 인수를 요소로 갖는 배열을 생성한다.
  • 전달된 인수가 1개이고 숫자이더라도 인수를 요소로 갖는 배열을 생성한다 (Array 생성자 함수랑 다름)

4.4 Array.from

  • ES6에서 도입. 유사 배열 객체 또는 이터러블 객체를 변환하여 새로운 배열을 생성한다.
    1
    2
    3
    4
    5
    6
    7
    // 문자열은 이터러블
    const arr1 = Array.from('hello');
    console.log(arr1); //['h', 'e', 'l', 'l', 'o']
    //
    // 유사 배열 객체를 새로운 배열로 변환하여 반환한다.
    const arr2 = Array.from({ length: 2, 0: 'a', 1: 'b'});
    console.log(arr2); // ['a', 'b']
  • Array.from을 사용하여 두번째 인수로 전달한 함수를 통해 값을 만들면서 요소를 채울 수 있다.
    두번째 인수로 전달한 함수는 첫번째 인수에 의해 생성된 배열의 요소값과 인덱스를 순차적으로 전달받아 새로운 요소를 생성할 수 있다.
    1
    2
    3
    const arr3 = Array.from({ length: 5 }, function (v, i) { return i; });
    console.log(arr3); // [0, 1, 2, 3, 4]
    //두번째 인수로 배열의 모든 요소에 대해 호출할 함수를 전달 할 수 있다.

5. 배열 요소의 참조

  • 배열 요소를 참조할 떄는 대괄호 []표기법을 사용한다. 안에는 인덱스가 와야한다.
  • 존재하지 않는 요소에 접근하면 undifined 반환된다.

6. 배열 요소의 추가와 갱신

  • 요소를 동적으로 추가할 수 있다.
  • length 프로퍼티 값은 자동 갱신된다.
  • length 프로퍼티 값보다 큰 인덱스로 요소를 추가하면 희소배열이 된다.
  • 이미 요소가 존재하는 요소에 값을 재할당하면 요소값이 갱신된다.
  • 정수 이외의 값을 인덱스처럼 사용하면 요소가 생성되는 것이 아니라 프로퍼티가 생성된다.
    이때 추가된 프로퍼티는 length 프로퍼티 값에 영향을 주지 않는다.

7. 배열 요소의 삭제

  • 특정 요소를 삭제하기 위해 delete 연산자를 사용할 수 있다.
  • 요소를 삭제하더라도 length 프로퍼티 값은 변하지 않아서 희소배열을 만든다. 안쓰는게 좋다.

8. 배열 메소드 (accessor method)

  • 직접 변경하지 않고 새로운 배열을 생성하여 반환하는 메소드 (accessor method)
  • 원본 배열을직접 변경하는 메소드 (mutator method)

8.1 Array.isArray

  • Array 생성자 함수의 정적 메소드 (Array.of, Array.from 또한 정적 메소드)
  • Array.isArray 주어진 인수가 배열이면 true, 아니면 false

8.2 Array.prototype.indexOf

원본 배열에서 인수로 전달된 요소를 검색하여 인덱스를 반환한다.

  • 중복되는 요소가 있는 경우, 첫번째 인덱스를 반환한다.
  • 해당하는 요소가 없는 경우, -1을 반환한다.
    1
    2
    3
    4
    const arr = [1, 2, 2, 4];
    arr.indexOf(2); // 1 요소 2를 검색하여 첫번째 인덱스를 반환
    arr.indexOf(4); // -1
    arr.IndexOf(2, 2); //두번째 인수는 검색을 시작할 인덱스이다.
  • indexOf 메소드는 배열에 요소가 존재하는지 확인할 때 유용하다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
const appleSeries = ['macbook', 'iphone', 'ipad', 'imac'];

if (appleSeries.indexOf('magicMouse') === -1) { // 배열에 'magicMouse' 가 있는지 확인
appleSeries.push('magicMouse'); // 존재하지 않으면 요소를 추가
}
console.log(appleSeries);

// ES7에서 새롭게 도입된 Array.prototype.includes 메소드가 더 가독성이 좋다.

const animals = ['cat', 'dog', 'pig'];

if (!animals.includes('snake')) {
animals.push('snake');
}
console.log(animals);
  • 결과값 -1을 비교해봐야하고, 배열에 NaN이 포함되어있는지 확인 불가 ( 단점 )

8.3 Array.prototype.push

  • push 메소드는 인수로 전달받은 모든 값을 원본 배열의 마지막 요소로 추가하고
  • 변경된 length 값을 반환한다.
  • push 메소드는 원본 배열을 직접 변경한다.
    1
    2
    3
    4
    5
    6
    // 또한 push 메소드는 원본 배열을 직접 변경하는 부수 효과가 있다.
    // ES6의 스프레드 문법을 사용하는 것이 좋다.

    const arr3 = [1, 2];
    const newArr = [... arr3, 3];
    console.log(newArr);

8.4 Array.prototype.pop

  • pop 메소드는 원본 배열에서 마지막 요소를 제거하고 제거한 요소를 반환한다.
  • 원본 배열이 빈 배열이면 undifined를 반환한다.
  • 원본 배열을 직접 변경한다.
    1
    2
    3
    4
    5
    const arr4 = [1, 2];

    let res = arr4.pop();
    console.log(res);
    console.log(arr4);

8.5 Array.prototype.unshift

  • 인수로 전달받은 모든 값을 원본 배열의 선두에 요소로 추가하고 변경된 length 값을 반환한다.
  • unshift 메소드는 원본 배열을 직접 변경한다.
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    const arra = [1, 2];

    let a = arra.unshift(3, 4);
    console.log(a); // 변경된 length 값을 반환
    console.log(arra);

    // 스프레드 문법을 쓰는 것이 더 좋다.

    const arra1 = [1, 2];
    const newArra = [3, ...arra1];
    console.log(newArra);

8.6 Array.prototype.shift

  • 원본 배열에서 첫번째 요소를 제거하고 제거한 요소를 반환한다.
  • 원본 배열이 빈 배열이면 undifined를 반호나한다.
  • shift 메소드는 원본 배열을 직접 변경한다.
    1
    2
    3
    4
    5
    const arra2 = [1, 2];

    let b = arra2.shift();
    console.log(b);
    console.log(arra2);

8.7 Array.prototype.concat

  • 인수로 전달된 값들을 원본 배열의 마지막 요소로 추가한 새로운 배열을 반환한다.
  • 인수로 전달한 값이 배열인 경우, 배열을 해체하여 새로운 배열의 요소로 추가한다.
  • 원본 배열은 변경되지 않는다.
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    const array1 = [1, 2];
    const array2 = [3, 4];

    let result3 = array1.concat(array2);
    console.log(result1);

    result1 = array1.concat(3);
    console.log(result1);

    result1 = array1.concat(array2, 5); // 두번째 값은 마지막 요소로 추가
    console.log(result1);
    console.log(array1);

    // concat 메소드는 ES6의 스프레드 문법으로 대체 가능하다
    result2 = [...[1, 2], ...[3, 4]];
    console.log(result2);
  • push , unshift 메소드 - 원본 배열을 직접 변경 (반드시 변수에 할당해야함)
  • concat 메소드 - 새로운 배열을 반환 (반환값을 반드시 변수에 할당 받아야함)
  • 스프레드 문법을 쓰자..!

8.8 Array.prototype.splice

  • 원본 배열의 중간에 요소를 추가하거나 제거하는 경우 사용
  • 3개의 매개변수가 있으며 원본 배열을 직접 변경한다.
    • start - 요소를 제거하기 시작할 인덱스. start만을 지정하면 start부터 모든 요소를
      제거한다. start가 음수인 경우, 배열의 끝에서의 인덱스를 나타낸다.
      -1이면 마지막 요소, -n이면 마지막에서 n번째 요소를 가리킨다.
    • deleteCount - start부터 제거할 요소의 개수. 0인 경우, 요소제거X
    • items - 제거한 위치에 삽입될 요소들의 목록, 생략가능 (옵션)
      생략할 경우 제거만 한다.
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      const arr = [1, 2, 3, 4];
      const result = arr.splice(1, 2, 20, 30);
      console.log(result); // [2, 3] 제거한 요소가 배열로 반환된다.
      console.log(arr); // [1, 20 , 30, 4]

      const result = arr.splice(1, 0, 100);
      console.log(arr); // [1, 100 ,2 ,3, 4]
      console.log(reusult); // []

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

8.9 Array.prototype.slice

  • 인수로 전달된 범위의 요소들을 복사하여 반환한다.
  • 원본 배열은 변경되지 않는다. 2개의 매개변수를 갖는다.
    • start - 복사를 시작할 인덱스. 음수인 경우, 배열의 끝에서 인덱스를 나타낸다.
      slice(-2)는 배열의 마지막 2개의 요소를 반환한다.
    • end - 복사를 종료할 인덱스. 이 인덱스에 해당하는 요소는 복사되지않는다.
      옵션이며 기본값은 length 값이다.
  • 인수를 모두 생략하면 원본 배열의 새로운 복사본을 생성하여 반환한다.
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    const arr = [1, 2, 3];
    let result = arr.slice(0, 1);
    console.log(result); //[1]
    console.log(arr); //[1, 2, 3]

    let result = arr.slice(-1);
    console.log(result) // [3]

    const copy = arr.slice();
    console.log(copy); //[1, 2, 3]
    console.log(copy === arr); // false
  • slice 메소드를 이용하여 arguments 같은 유사배열객체를 배열로 변환할 수 있다.

8.10 Array.prototype.join

  • 원본 배열의 모든 요소를 문자열로 변환한 후, 인수로 전달받은 값, 즉 구분자(separator)로
    연결한 문자열을 반환한다. 구분자는 생략가능하며 기본구분자는 , 이다
    1
    2
    3
    4
    5
    6
    7
    8
    const arr = [ 1, 2, 3, 4];

    let result = arr.join();
    console.log(result); // '1,2,3,4'
    result = arr.join('');
    console.log(result); // '1234'
    result = arr.join(':');
    console.log(result); // '1:2:3:4'

8.11 Array.prototype.reverse

  • 원본 배열의 요소 순서를 반대로 변경한다. 반환값은 변경된 배열이다.
    1
    2
    3
    4
    const arr = [1, 2, 3];
    const result = arr.reverse();
    console.log(arr); // [3, 2, 1]
    console.log(result); // [3, 2, 1]

8.12 Array.prototype.fill

  • ES6에서 새롭게 도입됌
  • 인수로 전달받은 값을 요소로 배열의 처음부터 끝까지 채운다.
  • 원본 배열이 변경된다.
  • 첫번째 인수 - 요소를 변경할 값
  • 두번째 인수 - 요소 채우기를 시작할 인덱스
  • 세번째 인수 - 채우기를 멈출 인덱스 (이 인덱스는 채우기에 포함되지 않음)
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    const arr = [1, 2, 3];
    arr.fill(0);
    console.log(arr); //[0, 0, 0]

    arr.fill(0, 1); // 0을 요소로 인덱스 1부터 채운다.
    console.log(arr); //[1, 0, 0]

    const arr = [1, 2, 3, 4, 5]
    arr.fill(0, 1, 3);
    console.log(arr); //[1, 0, 0, 4, 5]
  • 모든 요소를 하나의 값만으로 채울 수 밖에 없는 단점이 있다.

8.13 Array.prototype.includes

  • ES7에서 새롭게 도입
  • 배열 내에 특정 요소가 포함되어 있는지 확인하여 boolean값을 반환한다.
  • 첫번째 인수로 검색할 대상을 지정한다.
  • 두번째 인수로 검색을 시작할 인덱스를 전달할 수 있다. 생략할 경우, 기본값은 0
    음수를 전달하면 length와 음수 인덱스를 합산하여 (length+index)검색 시작 인덱스를 설정한다.
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    const arr = [1, 2, 3];
    let result = arr.includes(2);
    console.log(result); // true
    result =arr.includes(100);
    console.log(result); //false
    //
    result = arr.includes(1, 1); // 1이 포함되어 있는지 인덱스 1부터 검색
    console.log(result); // false
    result = arr.includes(3, -1);
    // 배열에 요소 3이 포함되어 있는지 인덱스 2부터 확인 (arr.length - 1)
    console.log(result); //true

8.14 Array.prototype.flat

  • ES10에서 새롭게 도입됌
  • 인수로 전달한 깊이만큼 재귀적으로 배열을 평탄화한다.
  • 인수로 중첩 배열을 평탄화할 깊이를 전달할 수 있다.
  • 기본값은 1, Infinity를 전달하면 중첩 배열 모두를 평탄화한다.
    1
    2
    3
    console.log(1, [2, 3, 4, 5]].flat()); //[1, 2, 3, 4, 5]
    console.log(1, [2, [3, [4, 5]]].flat(2)); //[1, 2, 3, [4, 5]]
    console.log(1, [2, 3, 4, 5]].flat(Infinity)); //[1, 2, 3, 4, 5]
You forgot to set the qrcode for Alipay. Please set it in _config.yml.
You forgot to set the qrcode for Wechat. Please set it in _config.yml.
You forgot to set the business and currency_code for Paypal. Please set it in _config.yml.
You forgot to set the url Patreon. Please set it in _config.yml.
Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×