티스토리 뷰

5.5 Array methods

여러 메소드들을 좀 더 알아보자.

Add/remove items

splice

배열 내부의 요소가 삭제되어도, 배열의 길이가 줄지는 않는다. delete는 값을 삭제하는 것이기 때문이다.

let arr = ["I", "go", "home"];

delete arr[1]; // remove "go"

alert( arr[1] ); // undefined

// now arr = ["I",  , "home"];
alert( arr.length ); // 3

보통 요소를 삭제하면 우리는 해당 배열의 길이도 자연스럽게 줄어드는 것을 기대하는데, 이를 위해 splice를 사용할 수 있다. 

let arr = ["I", "study", "JavaScript"];
arr.splice(1, 1); // from index 1 remove 1 element
alert( arr ); // ["I", "JavaScript"]

// --------------------------

let arr = ["I", "study", "JavaScript", "right", "now"];
// remove 3 first elements and replace them with another
arr.splice(2, 1, "Let's", "dance");
alert( arr ) // now ["I", "study", "Let's", "dance", "right", "now"]

// ---------------------------

// 요소를 삭제하지 않을 수도 있음. (deleteCount를 0으로 하면)
let arr = ["I", "study", "JavaScript"];

// from index 2
// delete 0
// then insert "complex" and "language"
arr.splice(2, 0, "complex", "language");

alert( arr ); // "I", "study", "complex", "language", "JavaScript"

slice

let arr = ["t", "e", "s", "t"];

alert( arr.slice(1, 3) ); // e,s (copy from 1 to 3)

alert( arr.slice(-2) ); // s,t (copy from -2 till the end)

concat

기존의 배열에서 추가적인 요소를 더해서 새로운 배열 생성

let arr = [1, 2];

// create an array from: arr and [3,4]
alert( arr.concat([3, 4]) ); // 1,2,3,4

// create an array from: arr and [3,4] and [5,6]
alert( arr.concat([3, 4], [5, 6]) ); // 1,2,3,4,5,6

// create an array from: arr and [3,4], then add values 5 and 6
alert( arr.concat([3, 4], 5, 6) ); // 1,2,3,4,5,6

// --------------------

let arr = [1, 2];

let arrayLike = {
  0: "something",
  length: 1
};

alert( arr.concat(arrayLike) ); // 1,2,[object Object]

특정 속성을 array-like 객체에 추가하면, 해당 객체는 concat 함수가 수행될 때 배열로 취급하여 요소를 삽입한다.

let arr = [1, 2];

let arrayLike = {
  0: "something",
  1: "else",
  [Symbol.isConcatSpreadable]: true,
  length: 2
};

alert( arr.concat(arrayLike) ); // 1,2,something,else

Iterate: forEach

arr.forEach(function(item, index, array) {
  // ... do something with an item
});

// for each element call alert
["Bilbo", "Gandalf", "Nazgul"].forEach(alert);

["Bilbo", "Gandalf", "Nazgul"].forEach((item, index, array) => {
  alert(`${item} is at index ${index} in ${array}`);
});

Searching in array

indexOf(item, from), lastIndexOf(item, from) 

let arr = [1, 0, false];

alert( arr.indexOf(0) ); // 1
alert( arr.indexOf(0, 2); // -1
alert( arr.indexOf(false) ); // 2
alert( arr.indexOf(null) ); // -1

alert( arr.includes(1) ); // 

// ----------------------
let fruits = ['Apple', 'Orange', 'Apple']

alert( fruits.indexOf('Apple') ); // 0 (first Apple)
alert( fruits.lastIndexOf('Apple') ); // 2 (last Apple)

find/findIndex

let result = arr.find(function(item, index, array) {
  // if true is returned, item is returned and iteration is stopped
  // for falsy scenario returns undefined
});

// -------------------------
let users = [
  {id: 1, name: "John"},
  {id: 2, name: "Pete"},
  {id: 3, name: "Mary"}
];

let user = users.find(item => item.id == 1);

alert(user.name); // John

// -------------------
let users = [
  {id: 1, name: "John"},
  {id: 2, name: "Pete"},
  {id: 3, name: "Mary"},
  {id: 4, name: "John"}
];

// Find the index of the first John
alert(users.findIndex(user => user.name == 'John')); // 0

// Find the index of the last John
alert(users.findLastIndex(user => user.name == 'John')); // 3

filter

let results = arr.filter(function(item, index, array) {
  // if true item is pushed to results and the iteration continues
  // returns empty array if nothing found
});

// --------------------------
let users = [
  {id: 1, name: "John"},
  {id: 2, name: "Pete"},
  {id: 3, name: "Mary"}
];

// returns array of the first two users
let someUsers = users.filter(item => item.id < 3);

alert(someUsers.length); // 2

 

 

Transform an array

배열을 새로운 자료구조로 변환하거나, 정렬하는 등 변환하는 메서드가 있다. 특히, sort, reverse, splice는 기존 배열자체를 변환시킨다는 것을 기억해두자.

map

let result = arr.map(function(item, index, array) {
  // returns the new value instead of item
});

// ------------------------
let lengths = ["Bilbo", "Gandalf", "Nazgul"].map(item => item.length);
alert(lengths); // 5,7,6

sort

sort 함수를 그냥 사용하면 예상과는 다른 결과가 나온다.

let arr = [ 1, 2, 15 ];

// the method reorders the content of arr
arr.sort();

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

이유는 sort가 수행될 때, 문자열로 변환 후 정렬하기 때문에 문자열 기준으로 요소가 정렬된다. 따라서, 추가적인 파라미터를 활용하여 정렬 규칙을 결정해 주어야 한다. (아래 코드 참고)

function compare(a, b) {
  if (a > b) return 1; // if the first value is greater than the second
  if (a == b) return 0; // if values are equal
  if (a < b) return -1; // if the first value is less than the second
}

// -------------------
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

자바에서는 Comparable, Comparator 와 같은 인터페이스가 정의되어 있어서, 해당 인터페이스를 구현하는 방식으로 정렬 규칙을 만들어 낸다. javascript에서는 그러한 타입보다도, 두 개의 값을 파라미터로 받고 number를 반환하기만 하면 되는 것 같다.

 

string 정렬은 아래 코드를 참고하자

let countries = ['Österreich', 'Andorra', 'Vietnam'];

alert( countries.sort( (a, b) => a > b ? 1 : -1) ); // Andorra, Vietnam, Österreich (wrong)

alert( countries.sort( (a, b) => a.localeCompare(b) ) ); // Andorra,Österreich,Vietnam (correct!)

split and join

split은 자바와 똑같다. 추가적인 파라미터가 있는 경우를 주의하자.

let arr = 'Bilbo, Gandalf, Nazgul, Saruman'.split(', ', 2);

alert(arr); // Bilbo, Gandalf

reduce/reduceRight

배열의 각 요소에 접근해서 반복적으로 로직을 수행해 나간다.

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

let result = arr.reduce((sum, current) => sum + current, 0);

alert(result); // 15

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

// removed initial value from reduce (no 0)
let result = arr.reduce((sum, current) => sum + current);

alert( result ); // 15

// ----------------------
let arr = [];

// Error: Reduce of empty array with no initial value
// if the initial value existed, reduce would return it for the empty arr.
arr.reduce((sum, current) => sum + current);

reduceRight도 동일한 동작을 하지만, 오른쪽에서 왼쪽으로 진행한다는 방향만 다르다.

Array.isArray

원래 배열은 object 타입으로 분류가 되지만, Array.isArray()을 통해 배열 여부를 확인할 수 있다.

Most methods support "thisArg"

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}
];

// find users, for who army.canJoin returns true
let soldiers = users.filter(army.canJoin, army);

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

 

그 외..

arr.fill(value, start, end) - 값을 start부터 end까지 채움

arr.copyWithin(target, start, end) - 값 복사

arr.flat(depth)/arr.flatMap(fn) - 새로운 다차원 배열을 일차원배열로 바꾼다.

댓글
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday