배열과 메서드 (2)

양주영·2021년 8월 25일
0

javascript

목록 보기
8/42

배열을 변형하는 메서드


배열을 변형시키거나 요소를 재정렬해주는 메서드에 대해 알아보자.

1. map
2. sort
3. reverse
4. split과 join
5. reduce와 reduceRight


- map

유용성과 사용빈도가 아주 높은 메서드 중 하나이다.
map은 배열 요소 전체를 대상으로 함수를 호출하고, 함수 호출 결과를 배열로 반환해준다.

let result = arr.map(function(item, index, array) {
  // 요소 대신 새로운 값을 반환합니다.
});

//문자열 길이 출력
let result = arr.map(function(item, index, array) {
  // 요소 대신 새로운 값을 반환합니다.
});


- sort(fn)

배열의 요소를 재정렬해준다. 배열 자체가 변경된다.
메서드를 호출하면 재정렬 된 배열이 반환되는데, 이미 arr 자체가 수정되었기 때문에 반환 값은 잘 사용되지 않는 편이다.

let arr = [ 1, 2, 15 ];

// arr 내부가 재 정렬됩니다.
arr.sort();

alert( arr );  // 1, 15, 2

=> 요소는 문자열로 취급되어 재 정렬되기 때문이다.

1부터 차례대로 정렬되지 않고, 15가 2보다 앞에 위치했다. 그 이유는 아스키 문자 기준으로 정렬할 때 일시적으로 숫자 타입을 문자열(String) 타입으로 형 변환하기 때문이다. 그리고 형 변환 이후, 첫번째 문자를 기준으로 비교하기 때문에 문자 “15”가 “2”보다 작은 아스키코드 값을 가지게 되는 것이다.

때문에, 새로운 정렬 기준을 만들기 위해 arr.sort()에 새로운 함수를 넘겨줘야 한다.

인수로 넘겨주는 함수는 반드시 값 두 개를 비교해야 하고 반환 값도 있어야 한다.

function compare(a, b) {
  if (a > b) return 1; // 첫 번째 값이 두 번째 값보다 큰 경우
  if (a == b) return 0; // 두 값이 같은 경우
  if (a < b) return -1; //  첫 번째 값이 두 번째 값보다 작은 경우
}

반환 값 < 0 : a가 b보다 앞에 있어야 한다.
반환 값 = 0 : a와 b의 순서를 바꾸지 않는다.
반환 값 > 0 : b가 a보다 앞에 있어야 한다. 

이제 배열 요소를 숫자 오름차순 기준으로 정렬해보자.

function compareNumeric(a, b) {
  if (a > b) return 1;
  if (a == b) return 0;
  if (a < b) return -1;
}

let arr = [ 1, 2, 15 ];

arr.sort(compareNumeric);

alert(arr);  // 1, 2, 15

정렬 함수는 어떤 숫자든 반환할 수 있다.
정렬 함수의 반환 값엔 제약이 없다. 양수를 반환하는 경우 첫 번째 인수가 두 번째 인수보다 '크다’를 나타내고, 음수를 반환하는 경우 첫 번째 인수가 두 번째 인수보다 '작다’를 나타내기만 하면 된다.

let arr = [ 1, 2, 15 ];

arr.sort(function(a, b) { return a - b; });

alert(arr);  // 1, 2, 15


- reverse

arr.reversearr의 요소를 역순으로 정렬시켜주는 메서드이다.

let arr = [1, 2, 3, 4, 5];
arr.reverse();

alert( arr ); // 5,4,3,2,1


- split과 join

  • str.split(delim)을 이용하면 구분자(delim)을 기준으로 문자열을 쪼개준다.
let names = 'Bilbo, Gandalf, Nazgul';

let arr = names.split(', ');

for (let name of arr) {
  alert( `${name}에게 보내는 메시지` ); // Bilbo에게 보내는 메시지
}
  • arr.join(glue)split과 반대이다. glue를 접착제처럼 사용해 배열 요소를 모두 합친 후 하나의 문자열을 만들어준다.
let arr = ['Bilbo', 'Gandalf', 'Nazgul'];

let str = arr.join(';'); // 배열 요소 모두를 ;를 사용해 하나의 문자열로 합칩니다.

alert( str ); // Bilbo;Gandalf;Nazgul


- reduce와 reduceRight

let value = arr.reduce(function(accumulator, item, index, array) {
  // ...
}, [initial]);

함수의 인수

  • accumulator – 이전 함수 호출의 결과. initial은 함수 최초 호출 시 사용되는 초깃값을 나타냄(옵션)
  • item – 현재 배열 요소
  • index – 요소의 위치
  • array – 배열
//reduce() 함수를 사용하여 1부터 10까지 더하는 예제이다.
const numberList = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
const initValue = 0;
const totalResult = numberList.reduce( (initialValue, item, index, array) => {
    return initialValue + item;
}, initValue);

alert(totalResult);

// 1. initValue 값(초기값)이 initalValue에 할당된다. 
// 2. item에는 배열의 첫 번째 요소인 1이 할당된다. 따라서 함수 값은 1이 된다.
// 3. 두 번째 호출 시, initialValue = 1 이고 여기에 배열의 두 번째 요소 2가 더해져 3이 된다.
// 4. 이 과정을 반복한다.

또한, 아래와 같이 초깃값을 생략하는 것도 가능하다.

let arr = [1, 2, 3, 4, 5];

// reduce에서 초깃값을 제거함(0이 없음)
let result = arr.reduce((sum, current) => sum + current);

alert( result ); // 15

하지만, 이렇게 초깃값 없이 reduce()를 사용할 경우
배열이 비어있는 상태면 reduce호출 시 에러가 발생하기 때문이다.
항상 초깃값을 명시해주자.

arr.reduceRightreduce와 동일한 기능을 하지만 배열의 오른쪽부터 연산을 수행한다는 점이 다르다.



Array.isArray로 배열 여부 알아내기


자바스크립트에서 배열은 독립적 자료형으로 취급되지 않고 객체형에 속한다.
따라서 typeof로는 일반 객체와 배열을 구분할 수가 없다.
구분하고 싶을 경우, Array.isArray(value) 메서드를 사용하자.
value가 배열이라면 true를, 아니라면 false를 반환해준다.

alert(Array.isArray({})); // false

alert(Array.isArray([])); // true


배열 메서드와 ‘thisArg’


함수를 호출하는 대부분의 배열 메서드(sort 제외)는 thisArg 라는 매개변수를 옵션으로 받을 수 있다.

arr.find(func, thisArg);
arr.filter(func, thisArg);
arr.map(func, thisArg);
// ...
// thisArg는 선택적으로 사용할 수 있는 마지막 인수입니다.

thisArgfuncthis가 된다.

let army = {
  minAge: 18,
  maxAge: 27,
  canJoin(user) {
    return user.age >= this.minAge && user.age < this.maxAge;
  }
};

let users = [
  {age: 16},
  {age: 20},
  {age: 23},
  {age: 30}
];

// army.canJoin 호출 시 참을 반환해주는 user를 찾음
let soldiers = users.filter(army.canJoin, army);

alert(soldiers.length); // 2
alert(soldiers[0].age); // 20
alert(soldiers[1].age); // 23

thisArgs에 army를 지정하지 않고 단순히 users.filter(army.canJoin)를 사용했다면 army.canJoin은 단독 함수처럼 취급되고, 함수 본문 내 this는 undefined가 되어 에러가 발생한다.



정리


  • 배열 변형하기
    - map(func) : 모든 요소에 func을 호출하고, 반환된 결과를 가지고 새로운 배열을 만듦
    - sort(func) : 배열을 정렬하고 정렬된 배열을 반환함
    - reverse() : 배열을 뒤집어 반환함
    - split/join – 문자열을 배열로, 배열을 문자열로 변환함
    - reduce(func, initial) : 요소를 차례로 돌면서 func을 호출함. 반환값은 다음 함수 호출에 전달함. 최종적으로 하나의 값이 도출됨

  • 기타
    - Array.isArray(arr) : arr이 배열인지 여부를 판단함.
    sort, reverse, splice는 기존 배열을 변형시킨다는 점에 주의하시기 바랍니다.



참조 : https://ko.javascript.info/array-methods

profile
뚜벅뚜벅

0개의 댓글