배열과 메서드

·2023년 3월 6일
0

배열 자체를 조작하는가? = 🟢
기존 배열은 건드리지 않고 조건을 적용한 새로운 배열을 반환하는가? = 🟠

요소 추가/제거 메서드

  • arr.push(...items) – 맨 끝에 요소 추가
  • arr.pop() – 맨 끝 요소 제거
  • arr.shift() – 맨 앞 요소 제거
  • arr.unshift(...items) – 맨 앞에 요소 추가

splice

splice 메서드를 사용하면 요소 추가, 삭제, 교체가 모두 가능합니다.

<script>
arr.splice(인덱스 번호[, 제거할 요소 개수, elem1, ..., elemN])
// 인덱스 번호는 제거 대상입니다.
</script>

요소 삭제하기

<script>
let arr = ["I", "study", "JavaScript"];

arr.splice(1, 1); // 인덱스 1부터(제거 대상에 포함) 요소 한 개를 제거

alert( arr ); // ["I", "JavaScript"]
</script>

요소를 삭제하고 교체하기

<script>
let arr = ["I", "study", "JavaScript", "right", "now"];

// 처음(0) 세 개(3)의 요소를 지우고, 이 자리를 다른 요소로 대체합니다.
arr.splice(0, 3, "Let's", "dance");

alert( arr ) // ["Let's", "dance", "right", "now"]
</script>

요소를 삭제하지 않고 추가하기

  • 제거할 요소 개수(deleteCount)를 0으로 설정
<script>
let arr = ["I", "study", "JavaScript"];

// 인덱스 2부터
// 0개의 요소를 삭제합니다.
// 그 후, "complex"와 "language"를 추가합니다.
arr.splice(2, 0, "complex", "language");

alert( arr ); // "I", "study", "complex", "language", "JavaScript"
// 인덱스 2부터 complex와 language를 끼워넣음
</script>

splice는 삭제된 요소로 구성된 배열을 반환할 수도 있습니다

<script>
let arr = ["I", "study", "JavaScript", "right", "now"];

// 처음 두 개의 요소를 삭제함
let removed = arr.splice(0, 2);

alert( removed ); // "I", "study" <-- 삭제된 요소로 구성된 배열
</script>

음수 인덱스도 사용 가능

  • slice 메서드 뿐만 아니라 배열 관련 메서드엔 음수 인덱스를 사용할 수 있습니다.
    이때 마이너스 부호 앞의 숫자는 배열 끝에서부터 센 요소 위치를 나타냅니다.
<script>
let arr = [1, 2, 5];

// 인덱스 -1부터 (배열 끝에서부터 첫 번째 요소)
// 0개의 요소를 삭제하고
// 3과 4를 추가합니다.
arr.splice(-1, 0, 3, 4);

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

객체 프로퍼티를 지우는 연산자 delete는 사용하지 않습니다.


slice

slice는 splice와 유사해 보이지만 훨씬 간단합니다.

  • "start" 인덱스부터 ("end"를 제외한) "end"인덱스까지의 요소를 복사한 새로운 배열을 반환합니다.(기존 배열 유지)
  • arr.slice는 문자열 메서드인 str.slice와 유사하게 동작하는데, arr.slice는 서브 문자열(substring) 대신 서브 배열(subarray)을 반환한다는 점이 다릅니다.
<script>
arr.slice([start], [end])
</script>

start와 end는 둘 다 음수일 수 있는데 이땐, 배열 끝에서부터의 요소 개수를 의미합니다.

<script>
let arr = ["t", "e", "s", "t"];

alert( arr.slice(1, 3) ); // e,s (인덱스가 1인 요소부터 인덱스가 3인 요소까지를 복사(인덱스가 3인 요소는 제외))

alert( arr.slice(-2) ); // s,t (인덱스가 -2인 요소부터 제일 끝 요소까지를 복사)
</script>

🛠️ arr.slice()는 인수를 하나도 넘기지 않고 호출하여 arr의 복사본을 만들 수 있습니다.
이런 방식은 기존의 배열을 건드리지 않으면서 배열을 조작해 새로운 배열을 만들고자 할 때 자주 사용됩니다.


conact

  • 기존 배열의 요소를 사용해 새로운 배열을 만들거나 기존 배열에 요소를 추가하고자 할 때 사용할 수 있습니다.
  • 인수엔 배열이나 값이 올 수 있는데, 인수 개수엔 제한이 없습니다.
<script>
arr.concat(arg1, arg2...)
</script>

메서드를 호출하면 arr에 속한 모든 요소와 arg1, arg2 등에 속한 모든 요소를 한데 모은 새로운 배열이 반환됩니다.

<script>
let arr = [1, 2];

// arr의 요소 모두와 [3,4]의 요소 모두를 한데 모은 새로운 배열이 만들어집니다.
alert( arr.concat([3, 4]) ); // 1,2,3,4

// arr의 요소 모두와 [3,4]의 요소 모두, [5,6]의 요소 모두를 모은 새로운 배열이 만들어집니다.
alert( arr.concat([3, 4], [5, 6]) ); // 1,2,3,4,5,6

// arr의 요소 모두와 [3,4]의 요소 모두, 5와 6을 한데 모은 새로운 배열이 만들어집니다.
alert( arr.concat([3, 4], 5, 6) ); // 1,2,3,4,5,6

</script>

인수 argN가 배열일 경우 배열의 모든 요소가 복사됩니다. 그렇지 않은경우(단순 값인 경우)는 인수가 그대로 복사됩니다.

유사배열

  • length 프로퍼티를 가진 객체를 유사 배열 객체라고 말합니다.

concat 메서드는 제공받은 배열의 요소를 복사해 활용합니다. 객체가 인자로 넘어오면 (배열처럼 보이는 유사 배열 객체이더라도) 객체는 분해되지 않고 통으로 복사되어 더해집니다.

<script>
let arr = [1, 2];

let arrayLike = {
  0: "something",
  length: 1 // length 프로퍼티를 인위적으로 추가함. 유사 배열 객체입니다.
};

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

인자로 받은 유사 배열 객체에 특수한 프로퍼티 Symbol.isConcatSpreadable이 있으면 concat은 이 객체를 배열처럼 취급합니다.
따라서 객체 전체가 아닌 객체 프로퍼티의 값이 더해집니다.

<script>
let arr = [1, 2];

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

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

forEach

forEach 메서드는 다음 매개변수(parameter)와 함께 배열의 각 요소에 적용하게 될 콜백 함수(callback function)를 전달합니다. 참고 블로그

순서대로
1. Current Value (명명된 매개변수) - 처리할 현재 요소(필수)
2. Index (선택적 매개변수) - 처리할 현재 요소의 인덱스
3. Array (선택적 매개변수) - forEach 메서드를 호출한 배열

우선 forEach 메서드를 사용해 배열을 순회하려면 콜백 함수 또는 익명 함수가 필요합니다.

<script>
const numbers = [1, 2, 3, 4, 5];

numbers.forEach(function() {
    // code
});
</script>

콜백 함수는 각 요소에 대해 실행되며, 배열의 요소를 나타내는 매개변수를 반드시 하나 이상 사용해야 합니다.

<script>
numbers.forEach(function(number) {
    console.log(number); // 1 2 3 4 5
});
</script>

필수 매개변수 다음 첫 번째 선택적 매개변수는 각 요소의 순서를 나타내는 인덱스입니다.

<script>
numbers.forEach((number, index) => {
    console.log('Index: ' + index + ' Value: ' + number);
}); /** 
Index: 0 Value: 1
Index: 1 Value: 2
Index: 2 Value: 3
Index: 3 Value: 4
Index: 4 Value: 5 **/
</script>

배열 매개변수는 원본 배열 그 자체입니다. 단순히 호출하기만 하면 배열의 요소 수만큼 배열이 출력되는 것을 볼 수 있습니다.

<script>
const numbers = [1, 2, 3, 4, 5];

numbers.forEach((number, index, array) => {
    console.log(array); /** 
    [1 2 3 4 5]
    [1 2 3 4 5]
    [1 2 3 4 5]
    [1 2 3 4 5]
    [1 2 3 4 5]
    **/
}); 

// 문자열 예시
["Bilbo", "Gandalf", "Nazgul"].forEach((item, index, array) => {
  alert(`${item} is at index ${index} in ${array}`);
}); /**
Bilbo is at index 0 in Billo, Gandalf, Nazgul
Gandalf is at index 1 in Billo, Gandalf, Nazgul
Nazgul is at index 2 in Billo, Gandalf, Nazgul
**/
</script>

배열 탐색하기

indexOf, lastIndexOf, includes

  • 같은 이름을 가진 문자열 메서드와 문법, 동작이 동일합니다.
    연산 대상이 문자열이 아닌 배열의 요소라는 점만 다릅니다.

    • arr.indexOf(item, from)는 인덱스 from부터 시작해 item(요소)을 찾습니다. 요소를 발견하면 해당 요소의 인덱스를 반환하고, 발견하지 못했으면 -1을 반환합니다.
    • arr.lastIndexOf(item, from)는 위 메서드와 동일한 기능을 하는데, 검색을 끝에서부터 시작한다는 점만 다릅니다.
    • arr.includes(item, from)는 인덱스 from부터 시작해 item이 있는지를 검색하는데, 해당하는 요소를 발견하면 true를 반환합니다.
<script>
let arr = [1, 0, false];

alert( arr.indexOf(0) ); // 1. 요소를 발견하면 해당 요소의 인덱스를 반환
alert( arr.indexOf(false) ); // 2
alert( arr.indexOf(null) ); // -1

alert( arr.includes(1) ); // true. 해당 요소를 발견하기만 하면
</script>

위 메서드들은 요소를 찾을 때 완전 항등 연산자 === 을 사용합니다.
false를 검색하면 정확히 false만을 검색하지, 0을 검색하진 않습니다.

includes는 NaN도 제대로 처리한다는 점에서 indexOf와 차이가 있습니다.

<script>
const arr = [NaN];
alert( arr.indexOf(NaN) ); // -1. NaN은 === 비교 연산자로 구분할 수 없습니다.
alert( arr.includes(NaN) );// true (NaN의 여부만 확인하였습니다.)
</script>

요소의 위치를 정확히 알고 싶을 때: arr.indexOf
요소가 배열 내 존재하는지 여부만 확인하고 싶을 때: arr.includes


find

특정 조건에 부합하는 객체를 배열 내에서 어떻게 찾을 수 있을까요?
객체로 이루어진 배열이 있다고 가정해 봅시다.
find 메서드는 함수의 반환 값을 true로 만드는 단 하나의 요소를 찾습니다.

<script>
let result = arr.find(function(item, index, array) {
  // true가 반환되면 반복이 멈추고 해당 요소를 반환합니다.
  // 조건에 해당하는 요소가 없으면 undefined를 반환합니다.
});
</script>

요소 전체를 대상으로 함수가 순차적으로 호출됩니다.

  1. item – 함수를 호출할 요소
  2. index – 요소의 인덱스
  3. array – 배열 자기 자신

예시) 배열 내에서 id == 1 조건을 충족하는 사용자 객체 찾기

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

위 예시에서 find 안의 함수 인자는 한 개입니다(item => item.id == 1)
다른 인자들(index, array)은 잘 사용되지 않습니다.

findIndex

arr.findIndex는 find와 동일한 일을 하나, 조건에 맞는 요소를 반환하는 대신 해당 요소의 인덱스를 반환한다는 점이 다릅니다. 조건에 맞는 요소가 없으면 -1이 반환됩니다.

<script>
let users = [
  { id: 1, name: "John" },
  { id: 2, name: "Pete" },
  { id: 3, name: "Mary" },
];

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

console.log(user); // 0 (id == 1의 인덱스 0을 반환)
</script>

filter

위에서 언급한 find 메서드는 함수의 반환 값을 true로 만드는 단 하나의 요소를 찾습니다.
조건을 충족하는 요소가 여러 개라면 arr.filter(fn)를 사용하면 됩니다.

<script>
let results = arr.filter(function(item, index, array) {
  // 조건을 충족하는 요소는 results에 순차적으로 더해집니다.
  // 조건을 충족하는 요소가 하나도 없으면 빈 배열이 반환됩니다.
});
</script>

예시)

<script>
let users = [
  {id: 1, name: "John"},
  {id: 2, name: "Pete"},
  {id: 3, name: "Mary"}
];

// 앞쪽 사용자 두 명을 반환합니다.
let someUsers = users.filter(item => item.id < 3);

console.log(someUsers.length); // 2
console.log(someUsers); // [ { id: 1, name: 'John' }, { id: 2, name: 'Pete' } ]
</script>

filter는 find와 문법이 유사하지만, 조건에 맞는 요소 전체를 담은 배열을 반환한다는 점에서 차이가 있습니다.


profile
저녁놀 마을 사람

0개의 댓글

관련 채용 정보