Array Useful

ES6+ 등장 이전부터 사용되었던 배열 객체의 알아두면 유용한 메서드를 정리합니다.

Array.isArray()

전달된 데이터의 타입이 배열인지 확인하여 Boolean 값을 반환합니다.

const o = {};
const a = [];

Array.isArray(a); // true
Array.isArray(o); // false

Array.prototype.forEach()

배열의 각 아이템을 순환하여 처리할 때 유용합니다. for문 또는 for..of문을 사용할 수도 있습니다.










 






const items = ['아이템1', '아이템2', '아이템3'];
const copy = [];

// for문
for (let i=0, l=items.length; i<l; ++i) {
  copy.push(items[i]);
}

// forEach 메서드
items.forEach(item => copy.push(item));

// for..of문
for (let item of items) {
  copy.push(item);
}

forEach 메서드에 2번째 인자를 전달할 경우, 전달된 인자는 this 컨텍스트가 됩니다. 아래 코드는 class Counteradd 메서드 내부에 forEach를 활용하면서 this 참조를 변경하는 예시입니다. this를 변경함으로 add 메서드 내부의 thisCounter 클래스의 인스턴스를 참조하게 됩니다.










 









class Counter {
  constructor() {
    this.sum = 0;
    this.count = 0;
  }
  add(array) {
    array.forEach(function(item) {
      this.sum += item;
      ++this.count;
    }, this);
  }
}

const obj = new Counter();
obj.add([9, 12, 3]);

console.log(obj.count); // 3
console.log(obj.sum); // 24

NOTE

화살표 함수 식을 사용하면 this 컨텍스트를 변경하지 않아도 됩니다. 화살표 함수 내부의 this는 상위 컨텍스트를 참조하므로 아래 코드에서 thisCounter 클래스의 인스턴스입니다.

add(array) {
  array.forEach(item => {
    this.sum += item;
    ++this.count;
  });
}

Array.prototype.map()

forEach 메서드와 유사하지만, 배열 객체의 아이템을 가공한 후 새로운 배열로 반환한다는 점이 다릅니다.













 
 
 

 

let items = ['아이템1', '아이템2', '아이템3'];
let copy = [];

// forEach 메서드를 사용할 경우
copy = items.forEach(item => {
  return item.replace(/아이템/g,'');
});

console.log(copy); // undefined


// map 메서드를 사용할 경우
copy = items.map(item => {
  return item.replace(/아이템/g,'');
});

console.log(copy); // ["1", "2", "3"]

NOTE

화살표 함수 식을 아래와 같이 간추려 표현하면 return 키워드를 생략할 수 있습니다.

copy = items.map(item => item.replace(/아이템/g,''));

Array.prototype.filter()

filter 메서드는 배열의 아이템 중 일부를 필터링(Filtering) 할 때 유용하게 사용됩니다.

const fruits = ['사과', '풋사과', '포도즙', '청포도', '망고', '바나나', '오렌지즙'];

/**
 * 검색 조건에 따른 배열 필터링(쿼리)
 */
const filterFruits = (query) => {
  return fruits.filter((fruit) => {
    return fruit.includes(query);
  });
};

console.log(filterFruits('사과')); // ['사과', '풋사과']
console.log(filterFruits('즙')); // ['포도즙', '오렌지즙']

NOTE

filterFruits 화살표 함수 식을 아래와 같이 점차적으로 함축하여 표현할 수도 있습니다.

  1. 매개변수의 괄호(()) 생략
const filterFruits = query => {
  return fruits.filter(fruit => {
    return fruit.includes(query);
  });
};
  1. 함수의 중괄호({}), return 키워드 생략
const filterFruits = query =>
  fruits.filter(fruit =>
    fruit.includes(query)
  );
  1. 인라인(1줄) 변경
const filterFruits = query => fruits.filter(fruit => fruit.includes(query));

Array.prototype.sort()

sort 메서드는 배열의 아이템을 오름 차순, 내림 차순으로 정렬(Sortering) 할 때 유용하게 사용됩니다. 비교함수는 선택적으로 전달할 수 있습니다. 비교함수의 매개 변수는 현재 아이템과 다음 아이템으로, 아이템을 비교하여 정렬 순서를 변경합니다.

array.sort([compareFunction]);

주의!

sort 메서드는 새로운 배열을 반환하는 것이 아니므로, 데이터를 보존하려면 복사된 배열을 사용해야 합니다.


 

const originalArray = ['원본', '배열', '데이터'];
const copyedArray = [...originalArray];

숫자 정렬

  • a - b 값이 0 보다 작으면, a가 먼저 배치 됩니다.
  • a - b 값이 0 보다 크면, b가 먼저 배치 됩니다.
  • a - b 값이 0 일 경우, a, b의 배치에 변화가 없습니다.



 
 
 



const numbers = [11, 92, 7, 3, -12, 32, -2];

// 오름차순 정렬
const sortedASC = [...numbers].sort((n1, n2) => {
  return n1 - n2;
});

console.log(sortedASC); // [-12, -2, 3, 7, 11, 32, 92]

NOTE

내림차순(DESC) 정렬의 경우는 비교함수 내 n2에서 n1을 빼면 됩니다.


 




const sortedDESC = [...numbers].sort((n1, n2) => {
  return n2 - n1;
});

console.log(sortedDESC); // [92, 32, 11, 7, 3, -2, -12]

문자 정렬

  • a > b 비교 값이 1이면, a가 먼저 배치 됩니다.
  • a > b 비교 값이 -1이면, b가 먼저 배치 됩니다.
  • a > b 비교 값이 0이면, a, b의 배치에 변화가 없습니다.


 
 
 




const fruits = ['사과', '풋사과', '포도즙', '청포도', '망고', '바나나', '오렌지즙'];

const orderedASC = [...fruits].sort((f1, f2) => {
  return f1 > f2 ? 1 : f1 < f2 ? -1 : 0;
});

// ㄱ-ㅎ 순으로 정렬
console.log(orderedASC); // ["망고", "바나나", "사과", "오렌지즙", "청포도", "포도즙", "풋사과"]

NOTE

내림차순(DESC) 정렬의 경우는 반대로 비교함수 내 f1 보다 f2가 클 경우, -1을 반환하도록 설정합니다.

const orderedDESC = [...fruits].sort((f1, f2) => {
  return f1 > f2 ? -1 : f1 < f2 ? 1 : 0;
});

// ㅎ-ㄱ 순으로 정렬
console.log(orderedDESC); // ["풋사과", "포도즙", "청포도", "오렌지즙", "사과", "바나나", "망고"]

객체 정렬

문자 비교와 비슷하지만, 정렬하고자 하는 객체의 속성을 비교한 후 결과를 반환해야 합니다.











 
 
 























const members = [
  { name: '박유나', score: 42 },
  { name: '손상경', score: 87 },
  { name: '민준현', score: 78 },
  { name: '김소라', score: 91 },
  { name: '서진욱', score: 65 },
  { name: '나영진', score: 97 },
];

const orderMembersBy = (type='name', ascDesc=1) => {
  const result = [...members].sort((m1, m2) => {
    return m1[type] > m2[type] ? 1 : m1[type] < m2[type] ? -1 : 0;
  });
  return ascDesc >= 0 ? result : result.reverse();
};

orderMembersBy('name');      // 이름 ㄱ-ㅎ순 정렬
orderMembersBy('name', -1);  // 이름 ㅎ-ㄱ순 정렬
orderMembersBy('score');     // 점수 낮은 순 정렬
orderMembersBy('score', -1); // 점수 높은 순 정렬

/* ---------------------------------------------------
// 검증
--------------------------------------------------- */
orderMembersBy('name').map(member => member.name);
// 출력: ["김소라", "나영진", "민준현", "박유나", "서진욱", "손상경"]

orderMembersBy('name', -1).map(member => member.name);
// 출력: ["손상경", "서진욱", "박유나", "민준현", "나영진", "김소라"]

orderMembersBy('score').map(member => member.score);
// 출력: [42, 65, 78, 87, 91, 97]

orderMembersBy('score', -1).map(member => member.score);
// 출력: [97, 91, 87, 78, 65, 42]

참고