tech.junha.kr

노트/JavaScript

Array

작성 수정

  • 배열은 여러 개의 데이터를 하나의 변수에 담아 관리할 수 있는 구조다.
  • 배열은 다양한 타입의 요소를 담을 수 있다.
  • 하지만 유사한 성격의 데이터를 효율적으로 관리하려면, 같은 타입의 값을 사용하자
  • [number, string, Object] → [number, number, number]

1. Looping over an array

const fruits = ['🍒', '🥭', '🍍'];

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

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

2. forEach 메서드

fruits.forEach((fruit) => console.log(fruit));
  • 모든 요소에 대해 한 번 씩 실행하는 의미가 강하다.
  • 반복도중 멈출 방법이 throw 밖에 없다.
  • 중간에 looping을 멈추고 싶으면 다른 코드를 사용하자.

3. Array.prototype.map(callback)

  • callback: function(item, index, array)
const numbers = [1, 2, 3, 4, 5];
const mappedNumbers = numbers.map((number) => {
  return number * 2;
});

// mappedNumbers
// [2, 4, 6, 8, 10];
// 내부 구현
function arrayPrototypeMap(callback) {
  let newArr = [];
  for (let i = 0 ; i < array.length; i++){
      newArr.push(callback(array[i]))
  }
  return newArr;
}
  • python 코드와 arg 순서 혼동 주의
    • for index, item in enumerate(array)

2. push, pop, unshift, shift 메서드

fruits.push('🥝');    // 뒤 삽입
fruits.pop();         // 뒤 제거

fruits.unshift('🥝')  // 앞 삽입
fruits.shift()        // 앞 제거
  • unshift, shift는 배열의 전체 요소가 움직이기 때문에 느리다.

3. splice

  • splice(*index, ?count, ?insertElement): 원본 변형
const array1 = [0, 1, 2, 3, 4, 5];
array1.splice(1); // [0]
array1.splice(1, 1); // [0, 2, 3, 4, 5]
array1.splice(1, 1, 7); // [0, 7, 2, 3, 4, 5]

contents.splice(i,1)
// 원본에서 i인덱스 하나만 지우기
  • 두번째 인자를 생략하면, array[index:] 두번째 인자부터 끝까지 엘리먼트를 포함시킨다.
  • 세번째 인자부터, 지운 인덱스에 엘리먼트를 추가할 수 있다.

4. concat

  • 배열을 합친 새로운 배열 반환
const arr1 = [0, 1, 2];
const arr2 = ['a', 'b'];

const newArr = arr1.concat(arr2);
 // [0, 1, 2, 'a', 'b']

5. indexof, includes, lastIndexof

  • 다음 메서드들은 Search에 관한 메서드이다.
const tools = ['a', 'b', 'c', 'd', 'e', 'a'];

// indexOf: return the index of value
tools.indexOf('b'); // 1
tools.indexOf('z'); // -1

// includes: return true of false
tools.includes('a'); // true
tools.includes('y'); // false

// lastIndexOf
tools.indexof('a'); // 0
tools.lastIndexof('a'); // 5

6. sort()

  • 원본 변형
const arr = [4, 2, 11, 1 ,3];
arr.sort()
// [1, 11, 2, 3, 4]
  • sort()는 아스키 코드 기준으로 정렬이 되어, 정상적으로 정렬되지 않는다.
  • arr.sort([compareFunction]) : 매개변수로 비교 함수를 넣어, 오름차순으로 정렬할 수 있다.
function compareNumbers(a, b) {
  return a - b;
}
// return 값이 음수이면 첫번째 인자 먼저 출력

arr.sort(compareNumbers) 
// [1, 2, 3, 4, 11]

7. join()

  • Array.prototye.join(separator?: string): string
  • 배열의 모든 요소들을 연결한 하나의 문자열을 반환한다.
  • separator: 배열의 요소를 구분할 문자열
  • arr.length=0 이면, 빈 문자열을 반환한다.
var arr = ['h','u','n','g','r','y']

arr.join()     // h,u,n,g,r,y
arr.join("")   // hungry

8. slice()

  • arr.slice([begin[, end]])
  • [begin, end-1]까지 얕은 복사를 통해 새로운 배열로 반환한다.
  • 원본 배열은 바뀌지 않는다.
  • 매개변수를 아무것도 넘기지 않으면, 원본 배열의 얕은 복사본을 반환한다.
const animals = ['ant', 'bison', 'camel', 'duck', 'elephant'];

animals.slice(2);
// slice(2) == slice(2,end) 
// ["camel", "duck", "elephant"]

animals.slice(2, 4);
// ["camel", "duck"]

animals.slice(1, 5);
// ["bison", "camel", "duck", "elephant"]

animals.slice(-2);
// slice(-2) == slice(-2, end) 
// ["duck", "elephant"]

animals.slice(2, -1);
// ["camel", "duck"]

animals.slice();
// ["ant", "bison", "camel", "duck", "elephant"]
  • every(), some(), find(), findIndex()는 각 요소를 판별 함수에 전달하고, 그 결과의 참/거짓 여부에 따라 반복의 종료 여부를 결정할 수 있음.

10. Array.prototype.filter(callback)

  • callback: function(element, index[, array])
  • true를 반환하면 요소를 유지하고, false를 반환하면 버린다.
const words = ['spray', 'limit', 'elite', 'exuberant', 'destruction', 'information', 'excellent'];

const result = words.filter(word => word.length > 6);
// ["exuberant", "destruction"]
function filter(callback) {
  let newArray = [];
  
  for (let i =0; i<array.length; i++) {
      if (callback(array[i])) {
          newArray.push(array[i]);
      }
  }

  return newArray;
}

11. Array.prototype.reduce(callback [,initialValue])

  • callback(accumulator, currentValue, ?currentIndex, ?array)
  • 배열의 정보를 하나의 값(acc)으로 변환하는 목적
  • acc: reduce 스택이 종료될 때 까지 사용하는 전역 변수
  • initialValue: 첫 번째 요소(default =0)
  • return: reducer에서 마지막으로 리턴한 값
const arr = [1, 2, 3, 4];
const reducer = (acc, cur) => acc + cur;

arr.reduce(reducer, 0);
// expected output: 0 + 1 + 2 + 3 + 4 = 10

initialValue 오류

  • 빈 배열에서 초기값 없이 reduce를 호출하면 undefined오류 발생

  • initValue를 설정하지 않으면, acc는 배열의 첫번째 요소가 되므로, 0을 넣어 합산 값을 초기화해야한다.

data = [{...}, {...}, {...}]

data.reduce((acc,cur)=> acc + cur.price * cur.num)
// '[object Object]920015300' ❌

data.reduce((acc,cur)=> acc + cur.price * cur.num, 0)
// 120000 ✅

Promise 활용 예시

  • 프로미스를 반환하는 비동기 함수들을 동기적으로 실행하고 싶을 때 사용
  • 콜백이 실행 된 뒤 또다시 같은 콜백에 무언가를 전달할 수 있는 능력을 활용
const iterable = [fn1, fn2, fn3]
// functions that asynchronous which return a promise

iterable.reduce((p, fn) => p.then(fn), Promise.resolve())
//  promise.then(fn1).then(fn2).then(fn3)
  • Promise.resolve()
    • 이행된 Promise 반환
    • then을 가질 수 있는 값이기 때문에 바로 동기 호출 가능
  • 모든 배열을 순회하는 reduce함수가 호출된 콜백 함수를 기다리며, 동기적으로 호출 된다.
const promiseFactory = (time) => {
  return new Promise((resolve, reject) => {
    console.log(time); 
    setTimeout(resolve, time);
  });
};

[1000, 2000, 3000, 4000].reduce((acc, cur) => {
  return acc.then(() => promiseFactory(cur));
}, Promise.resolve());
// 바로 1000
// 1초 후 2000
// 2초 후 3000
// 3초 후 4000

12. Array.prototype.entries()

  • 배열의 각 인덱스에 대한 키/값 쌍을 가지는 새로운 Array Iterator 객체를 반환한다.
var a = ['a', 'b', 'c'];
var iterator = a.entries();

for (let e of iterator) {
  console.log(e);
}

// [0, 'a']
// [1, 'b']
// [2, 'c']

console.log(iterator) // Array Iterator {next:function}

13. Array.prototype.find(callback)

  • 판별 함수를 만족하는 첫 번째 요소의 값 반환
  • 없으면 undefined 반환
const array1 = [5, 12, 8, 130, 44];

const found = array1.find(element => element > 10);
// 12

Array.prototype.some(callback)

  • boolean 반환
  • 특정 조건을 만족하는 요소가 하나라도 있는지 확인
const array = [1, 3, 5, 6, 7];

array.some((element) => element % 2 === 0;); // 짝수가 하나라도 있는지 확인
// true

Array.from()

  • Array.from(arrayLike[, mapFn[, thisArg]])
  • 유사 배열 객체(array-like object), 반복 가능한 객체(iterable object)를 얕게 복사해 새로운 Array 객체 반환
  • String 객체는 length 프로퍼티를 소유하고 있으므로 유사 배열 객체이다.
const string = 'hello world';

Array.from(string);
// ['h', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd']

Array.prototype.reverse()

  • 원본 변형
const duplicated = [...arr].reverse()
// 복사 후 사용

examples

알파벳 카운터(메소드 체이닝)
const AlphabetCounter = {
  sentence: '',
  alphabetMap: {},

  setSentence: function (sentence) {
    this.sentence = sentence;
    return this;
  },

  buildAlphabetMap: function () {
    this.alphabetMap = this.sentence
      .trim()
      .toLowerCase()
      .split('')
      .filter((c) => c >= 'a' && c <= 'z')
      .reduce((map, char) => {
        if (!map[char]) map[char] = 0;
        map[char]++;
        return map;
      }, {});
    return this;
  },

  buildResult: function () {
    const resultString = Object.entries(this.alphabetMap)
      .reduce((acc, [alphabet, freq]) => `${acc} [${alphabet}: ${freq}]`, '')
      .trim();
    return `결과는 : ${resultString} 입니다.`;
  },
};

export default AlphabetCounter;