/ JAVASCRIPT

JavaScript(7) - array

JavaScript 관련 포스팅

Declaration

  • new keyword 사용
  • [ ] 사용 ★★★★★
    const arr1 = new Array();
    const arr2 = [1, 2];
    

Index position

  • array의 마지막 element를 찾을 때는 [array.length-1] 를 사용함

    const fruits = ['🍦','🍉'];
    console.log(fruits);
    console.log(fruits[2]); // undefined
    console.log(fruits[fruits.length-1]);
    
    Console

    (2) [‘🍦’, ‘🍉’]
    undefined
    🍉

Looping over an array

a. for loop

  console.log(fruits);

  for(let i = 0; i < fruits.length; i++) {
      console.log(fruits[i]);
  }
Console

(2) [‘🍦’, ‘🍉’]
🍦
🍉

b. for of

  console.log(fruits);

  for(let fruit of fruits){
      console.log(fruit);
  }
Console

(2) [‘🍦’, ‘🍉’]
🍦
🍉

c. forEach

  • array에 들어있는 각 element마다 함수를 수행함
  • 전달한 callback 함수를 value마다 호출

    console.log(fruits);
    
    fruits.forEach(function (fruit, index, array) {
        console.log(fruit, index, array);
    });
    

    (※ 보통, forEach에서 array는 잘 받아오지 않음)

    Console

    (2) [‘🍦’, ‘🍉’]
    🍦 0 ▶ (2) [‘🍦’, ‘🍉’]
    🍉 1 ▶ (2) [‘🍦’, ‘🍉’]

    console.log(fruit, index, array);
    
    Console

    🍦 0 ▶ (2) [‘🍦’, ‘🍉’]
    🍉 1 ▶ (2) [‘🍦’, ‘🍉’]

    console.log(fruit, index);
    
    Console

    🍦 0
    🍉 1

    console.log(fruit);
    
    Console

    🍦
    🍉

    Arrow function에서,
    logic이 한 줄이면 {} curly braces와 ; semicolon을 지울 수 있음

    // Arrow function
    fruits.forEach((fruit, index) => console.log(fruit, index));
    fruits.forEach((fruit) => console.log(fruit));
    

Addition, deletion and copy

a. push

  • 배열의 마지막에 element를 더해줌

    console.log(fruits);
    fruits.push('🍑', '🥝');
    console.log(fruits);
    
    Console

    (2) [‘🍦’, ‘🍉’]
    (4) [‘🍦’, ‘🍉’, ‘🍑’, ‘🥝’]

b. pop

  • 배열의 마지막 element를 제거
    console.log(fruits);
    fruits.pop();
    fruits.pop();
    console.log(fruits);
    
    Console

    (4) [‘🍦’, ‘🍉’, ‘🍑’, ‘🥝’]
    (2) [‘🍦’, ‘🍉’]

c. unshift

  • 배열 시작에 element를 더함
    console.log(fruits);
    fruits.unshift('🍌', '🍍');
    console.log(fruits);
    
    Console

    (2) [‘🍦’, ‘🍉’]
    (4) [‘🍌’, ‘🍍,’🍦’, ‘🍉’]

d. shift

  • 배열의 element를 제거함

    console.log(fruits);
    fruits.shift();
    console.log(fruits);
    
    Console

    (4) [‘🍌’, ‘🍍,’🍦’, ‘🍉’]
    (3) [‘🍍,’🍦’, ‘🍉’]

배열의 ‘마지막’에 element를 넣고 빼는 pushpop 이 빠름

배열의 ‘시작’에 element를 넣고 빼는 shiftunshift 는 느림

⇒ 배열 시작 지점(index[0])에 item을 넣으려면 기존의 item들을 뒤로 이동 후 새 item을 넣어야 하며, 반대로 배열 시작 지점(index[0])의 item을 빼면, 이후의 item들을 앞으로 이동해야 하기에 시간이 오래 걸림

e. splice

  • ( vs. slice : 배열 자체의 수정 없이 특정 부분 리턴 )
  • splice(index number) : 해당 index부터 끝까지 지움
  • splice(index number, 지우려는 개수) : 해당 index부터 개수 만큼 지움
  • splice(index number, 지우려는 개수, 'item1', 'item2') : 해당 index부터 개수만큼 지우고 item1, item2 추가

    console.log(fruits);
    fruits.splice(4);
    console.log(fruits);
    fruits.splice(0, 2);
    console.log(fruits);
    fruits.splice(1, 1, '🍇', '🍏');
    console.log(fruits);
    
    Console

    (6) [‘🍍,’🍦’, ‘🍉’, ‘🍈’, ‘🥥’, ‘🍊’]
    (4) [‘🍍,’🍦’, ‘🍉’, ‘🍈’]
    (2) [‘🍉’, ‘🍈’]
    (3) [‘🍉’, ‘🍇’, ‘🍏’]

f. slice

  • ( vs. splice : 기존 배열 자체를 수정함)
  • 배열의 특정한 부분을 배열로 리턴
  • slice(시작 index, 끝나는 index);
    ※ 이때, 끝나는 index는 배제됨(exclusive)!

    const array = [1, 2, 3, 4, 5];
    const result = array.slice(2,5);
    console.log(result);
    console.log(array);
    
    Console

    (3) [3, 4, 5]
    (5) [1, 2, 3, 4, 5]

g. concat

  • 서로 다른 두 배열을 연결함
    array이름.concat(연결할 array);

      console.log(fruits);
      const food = ['🍕', '🍔'];
      const newFood = fruits.concat(food);
      console.log(newFood);
    
    Console

    (3) [‘🍉’, ‘🍇’, ‘🍏’]
    (5) [‘🍉’, ‘🍇’, ‘🍏’, ‘🍕’, ‘🍔’]

Searching

a. indexOf

  • array이름.indexOf('index를 알고 싶은 element', [검색을 시작할 index]);
  • 배열 내에 item이 처음 등장하는 index 반환 (vs. lastIndexOf)
  • 해당 array에 없는 item일 경우 -1 반환

    console.log(fruits);
    console.log(fruits.indexOf('🍇'));
    
    Console

    (3) [‘🍉’, ‘🍇’, ‘🍏’]
    1

  • 요소의 모든 index찾기

    let indices = [];
    let array = ['a', 'b', 'a', 'c', 'a', 'd'];
    let element = 'a';
    let idx = array.indexOf(element);
    while (idx != -1) {
      indices.push(idx);
      idx = array.indexOf(element, idx + 1);
    }
    console.log(indices); // [0, 2, 4]
    

    참고: Array.prototype.indexOf() - JavaScript | MDN

b. lastIndexOf

  • 배열 내에 둘 이상의 같은 element가 있을 때, 마지막 element의 index를 반환함
  • array이름.lastIndexOf('index를 알고 싶은 element');

    console.log(fruits);
    console.log('indexOf');
    console.log(fruits.indexOf('🍎'))
    console.log('lastIndexOf');
    console.log(fruits.lastIndexOf('🍎'));
    
    Console

    (5) [‘🍎’, ‘🍉’, ‘🍇’, ‘🍏’, ‘🍎’]
    0
    4

c. includes

  • array이름.includes('element');
  • 특정 element가 배열에 존재하는지 확인할 때
  • true/false 반환

    console.log(fruits);
    console.log(fruits.includes('🍏')); // true
    console.log(fruits.includes('🍤')); // false
    
    Console

    (5) [‘🍎’, ‘🍉’, ‘🍇’, ‘🍏’, ‘🍎’]
    true
    false

d. find

  find<S extends T>(predicate: (this: void, value: T, index: number, obj: T[]) => value is S, thisArg?: any): S | undefined;
  • 전달된 predicate(callbackfn)가 첫 번째로 true인 요소를 만나면 그 값을 반환
    (아니면 undefined 반환)하며 predicate는 종료됨
  • predicate(value, index, obj)는 배열의 각 요소마다 적용되며, boolean을 반환

    class Student {
      constructor(name, age, enrolled, score) {
        this.name = name;
        this.age = age;
        this.enrolled = enrolled;
        this.score = score;
      }
    }
    
    const students = [
      new Student('A', 29, true, 45),
      new Student('B', 28, false, 80),
      new Student('C', 30, true, 90),
      new Student('D', 40, false, 66),
      new Student('E', 18, true, 88),
    ];
    const result = students.find((student)=>student.score === 90);
    console.log(result);
    
    Console
    ▶ Student {name: ‘C’, age: 30, enrolled: true, score: 90}

e. filter

  filter<S extends T>(predicate: (value: T, index: number, array: T[]) => value is S, thisArg?: any): S[];
  • predicate(callbackfn)를 전달해 이 함수가 true인 배열의 요소들만 모아 새 배열을 반환

    const result = students.filter((student)=>student.enrolled === true);
    console.log(result);
    
    Console
    ▶ (3) [Student, Student, Student]
    ▶ 0: Student {name: ‘A’, age: 29, enrolled: true, score: 45}
    ▶ 1: Student {name: ‘C’, age: 30, enrolled: true, score: 90}
    ▶ 2: Student {name: ‘E’, age: 18, enrolled: true, score: 88}
    length: 3
    ▶ [[Prototype]]: Array(0)

String

a. join

  join(separator?: string): string;
  • 배열의 모든 요소들을 더해서 string으로 반환
  • (opt) 원하는 separator(구분자)를 넣어서 반환할 수 있음

    const fruits = ['apple', 'banana', 'orange'];
    const result1 = fruits.join();
    const result2 = fruits.join('\n');
    const result3 = fruits.join('|');
    console.log(result1);
    console.log(result2);
    console.log(result3);
    
  • result1: w/o separator
    Console

    apple, banana, orange

  • result2: separator \n
    Console

    apple
    banana
    orange

  • result3: separator: |
    Console
    apple|banana|orange

b. split

split(separator: string | RegExp, limit?: number): string[];
  • separator(string 또는 정규표현식(RegExp))에 따라 여러 가지 문자열을 나눠 줌
  • (opt) limit에 반환할 배열의 크기를 지정할 수 있음

    const fruits = '🍎, 🥝, 🍌, 🍒';
    const result1 = fruits.split(', ');
    const result2 = fruits.split(', ', 3);
    console.log(result1);
    console.log(result2);
    
    Console

    (4) [“🍎”, “🥝”, “🍌”, “🍒”]
    (3) [“🍎”, “🥝”, “🍌”]

c. reverse

reverse(): T[];
  • 배열의 순서를 거꾸로 만들어 리턴
    ※ (주의) 배열 자체가 변화됨!
    const array = [1, 2, 3, 4, 5];
    const result = array.reverse();
    console.log(result);
    console.log(array);
    
    Console

    (5) [5, 4, 3, 2, 1]
    (5) [5, 4, 3, 2, 1]

d. sort

sort(compareFn?: (a: T, b: T) => number): this;
  • compareFn(callbackfn)에 이전 값(a)과 현재 값(b)이 전달됨
  • a - b의 결과가 음수이면, a < b 이므로 a, b 순서로 정렬됨
  • b, a 순서로 정렬하고 싶다면, b - a 를 리턴하게 하면 됨

e. map

map<U>(callbackfn: (value: T, index: number, array: T[]) => U, thisArg?: any): U[];
  • 배열 내의 각 요소들이 callbackfn에 의해 다른 값으로 mapping되어 반환
  // students의 score만 배열로 반환
  const result = students.map((student)=>student.score);
  console.log(result);
Console

(5) [45, 80, 90, 66, 88]

f. some

some(predicate: (value: T, index: number, array: T[]) => unknown, thisArg?: any): boolean;
  • 배열의 요소 중 predicate(callbackfn)를 만족하는 것이 하나라도 있는지 확인함
  • ( vs. every : 배열의 요소 전부가 predicate(callbackfn)를 만족하는지 확인)

    // student의 score가 50점 미만인 요소가 있는지 확인
    const result = students.some((student) => student.score < 50);
    console.log(result);
    
    Console

    true

g. reduce

reduce(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T): T;  
reduce(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T, initialValue: T): T;
  • 원하는 시작부터 배열의 모든 요소의 값을 누적
  • return값 정의 필수
  • previousValue : 이전에 callbackfn에서 리턴한 값
  • currentValue : 배열의 요소를 순차적으로 전달 받은 값
  • initialValue를 지정할 수 있음

    // student score의 평균 구하기
    const result = students.reduce((prev, curr) => prev + curr.score, 0);
    console.log(result/students.length);
    
    Console

    73.8

tip!

  • map, filter, join과 같이 배열 자체를 리턴하는 함수들은 서로 섞어서 사용이 가능

    const result = students
      .map((student) => student.score)
      .filter((score) => score > 50)
      .join(', ');
      console.log(result.toString());
    
    Console

    80, 90, 66, 88

< 출처 >

‘자바스크립트 8. 배열 제대로 알고 쓰자. 자바스크립트 배열 개념과 APIs 총정리 | 프론트엔드 개발자 입문편 (JavaScript ES6 ),’ 유튜브 비디오, 32:07, 게시자 ‘드림코딩 by 엘리,’ 2020년 5월 17일, https://youtu.be/tJieVCgGzhs

‘자바스크립트 9. 유용한 10가지 배열 함수들. Array APIs 총정리 | 프론트엔드 개발자 입문편 ( JavaScript ES6),’ 유튜브 비디오, 37:13, 게시자 ‘드림코딩 by 엘리,’ 2020년 5월 24일, https://youtu.be/tJieVCgGzhs