자바스크립트 배열

자바스크립트 배열 (array)은 다양한 데이터 타입을 순서대로 저장하는 자료구조 입니다

다음과 같은 특징이 파이썬의 리스트와 유사합니다.

  • 각 요소에 인덱스로 접근 가능
  • 동적으로 크기가 조절될 수 있는 것
  • 다양한 자료형이 요소로 가능

배열은 대괄호 [ ]를 사용하여 생성하며, 배열 내의 요소들은 콤마로 구분됩니다.

let arr = [1,2,3, 'a', 'b']

자바스크립트 배열 사용법

배열이 가지는 메소드와 속성을 이용하여 많은 조작을 할 수 있습니다.

length

배열의 길이를 나타내는 속성입니다. 함수가 아니므로 length()가 아닌 length로 사용합니다.

let fruits = ['apple', 'banana', 'orange'];
console.log(fruits.length); // 3

인덱싱

배열의 특정 위치에 있는 요소에 접근합니다.

let fruits = ['apple', 'banana', 'orange'];
console.log(fruits[1]); // 'banana'

push()

배열의 끝에 하나 이상의 요소를 추가합니다.

let fruits = ['apple', 'banana'];
fruits.push('orange');
console.log(fruits); // ['apple', 'banana', 'orange']

pop()

배열의 마지막 요소를 제거합니다

let fruits = ['apple', 'banana', 'orange'];
fruits.pop();
console.log(fruits); // ['apple', 'banana']

shift()

배열의 첫 번째 요소를 제거합니다

let fruits = ['apple', 'banana', 'orange'];
fruits.shift();
console.log(fruits); // ['banana', 'orange']

unshift()

배열의 맨 앞에 하나 이상의 요소를 추가합니다.

let fruits = ['banana', 'orange'];
fruits.unshift('apple');  // 하나의 요소 추가
console.log(fruits); // ['apple', 'banana', 'orange']
let fruits = ['banana', 'orange'];
fruits.unshift('apple', 'pineapple');  // 2개 요소 추가
console.log(fruits); // ['apple', 'pineapple', 'banana', 'orange']

splice()

배열의 특정 위치에서 요소를 추가하거나 제거합니다.

요소 추가

splice(index, 0, item1, item2, …)을 사용하여 특정 인덱스에 요소를 추가할 수 있습니다.

let fruits = ['apple', 'banana', 'orange'];
fruits.splice(1, 0, 'grape', 'kiwi');
console.log(fruits); // ['apple', 'grape', 'kiwi', 'banana', 'orange']

요소 제거

splice(index, count)를 사용하여 특정 인덱스부터 지정된 개수의 요소를 제거할 수 있습니다.

let fruits = ['apple', 'grape', 'kiwi', 'banana', 'orange'];
fruits.splice(1, 2);
console.log(fruits); // ['apple', 'banana', 'orange']

요소 교체

splice(index, count, item1, item2, …)를 사용하여 특정 인덱스부터 지정된 개수의 요소를 제거하고 새로운 요소로 교체할 수 있습니다

let fruits = ['apple', 'grape', 'kiwi', 'banana', 'orange'];
fruits.splice(1, 2, 'mango', 'pear');
console.log(fruits); // ['apple', 'mango', 'pear', 'banana', 'orange']

마지막 요소 제거

splice(-1, 1)을 사용하여 배열의 마지막 요소를 제거할 수 있습니다.

let fruits = ['apple', 'mango', 'pear', 'banana', 'orange'];
fruits.splice(-1, 1);
console.log(fruits); // ['apple', 'mango', 'pear', 'banana']

concat()

배열을 다른 배열이나 값과 합칩니다

let fruits1 = ['apple', 'banana'];
let fruits2 = ['orange', 'grape'];
let combinedFruits = fruits1.concat(fruits2);
console.log(combinedFruits); // ['apple', 'banana', 'orange', 'grape']

slice()

배열의 일부분을 추출하여 새로운 배열을 만듭니다.

let fruits = ['apple', 'banana', 'orange', 'grape'];
let slicedFruits = fruits.slice(1, 3);
console.log(slicedFruits); // ['banana', 'orange']

slice() 함수에 아무런 인자를 넣지 않으면 배열 복사가 됩니다.

let originArr = [1,2,3];
let copyArr = originArr.slice()
console.log(copyArr)  // [ 1, 2, 3 ]

includes()

특정 요소가 배열에 포함되어 있는지 여부를 확인합니다.

let fruits = ['apple', 'banana', 'orange'];
console.log(fruits.includes('banana')); // true

join()

배열의 모든 요소를 문자열로 결합합니다.

let fruits = ['apple', 'banana', 'orange'];
let result = fruits.join(', ');
console.log(result); // 'apple, banana, orange'

filter()

주어진 함수의 조건을 만족하는 요소들로 새로운 배열을 생성합니다.

let numbers = [1, 2, 3, 4, 5];
let evenNumbers = numbers.filter(num => num % 2 === 0);
console.log(evenNumbers); // [2, 4]

map()

배열의 모든 요소에 주어진 함수를 적용한 결과로 새로운 배열을 생성합니다.

let numbers = [1, 2, 3, 4, 5];
let squaredNumbers = numbers.map(num => num * num);
console.log(squaredNumbers); // [1, 4, 9, 16, 25]

split()

문자열을 특정 구분자를 기준으로 나누어 배열로 반환합니다.

let sentence = 'Hello, World!';
let words = sentence.split(' ');
console.log(words); // ['Hello,', 'World!']

indexOf()

배열에서 특정 요소의 인덱스를 반환하며, 해당 요소가 없으면 -1을 반환합니다.

let fruits = ['apple', 'banana', 'orange'];
console.log(fruits.indexOf('banana')); // 1

findIndex()

주어진 판별 함수를 만족하는 첫번째 요소를 반환합니다.

만약 어떤 요소도 조건을 만족하지 않으면 -1을 반환합니다.

const numbers = [10, 20, 30, 40, 50];

const index = numbers.findIndex(element => element > 30);

console.log(index); // 2

배열 반복문

for loop

const myArray = ['apple', 'banana', 'cherry'];

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

for…of 반복문

const myArray = ['apple', 'banana', 'cherry'];

for (const element of myArray) {
  console.log(element);
}

‘entries’ 메소드는 ‘for…of’ 루프와 함께 사용하여 인덱스와 요소 모두를 반복할 수 있습니다.

const myArray = ['apple', 'banana', 'cherry'];

for (const [index, element] of myArray.entries()) {
  console.log(`Index: ${index}, Element: ${element}`);
}

forEach

forEach문은 콜백 함수를 사용하여 각 요소를 반복하는 간결한 방법입니다.

const myArray = ['apple', 'banana', 'cherry'];

myArray.forEach((element) => {
  console.log(element);
});

배열 복사

Note: 밑에서 소개할 얕은 복사 방법은 단순한 요소로만 이루어진 배열에서는 깊은 복사 방법이 됩니다.

말만 들어서는 헷갈릴 수 있는데요. 이중 배열에서 얕은 복사 방법인 slice()의 예를 우선 보겠습니다.

let originalArray = [1, 2, [10,11]];
let shallowCopy = originalArray.slice();

shallowCopy[2][0] = 99; // 내부 배열를 변경하면 원본에도 영향을 미침

console.log(originalArray); // [ 1, 2, [ 99, 11 ] ]
console.log(shallowCopy);   // [ 1, 2, [ 99, 11 ] ]

내부 배열를 변경하면 원본에도 영향을 미치는 것을 확인 할 수 있습니다.

하지만 동일한 slice() 메소드로 복사하는 데 이번에는 내부 배열이 아니라 originalArray의 첫번째 요소를 바꿔보겠습니다.

let originalArray = [1, 2, [10,11]];
let deepCopy = originalArray.slice();

deepCopy[0] = 99; // 동일한 slice()인데 이번에는 deepcopy

console.log(originalArray); // [ 1, 2, [ 10, 11 ] ]
console.log(deepCopy);   // [ 99, 2, [ 10, 11 ] ]

동일한 copy 방법인데 이번에는 깊은 복사처럼 작동하였습니다.

이와 같이 어떤 경우에는 깊은 복사가 되더라도 배열 안의 배열이나 객체는 깊은 복사가 안되고 참조만 되는 것을 알 수 있습니다.

이 부분에 주의해서 복사를 해야 합니다. 그럼 얕은 복사법과 깊은 복사법에 대해 알아볼까요?

얕은 복사 (Shallow Copy)

얕은 복사는 원본 객체의 최상위 레벨에서만 새로운 객체가 생성되고, 내부의 객체(들)은 원본과 동일한 객체를 참조합니다. 즉, 내부 객체의 변경은 복사된 객체와 원본 객체에 영향을 미칩니다.

얕은 복사를 하는 방법은 여러가지가 있습니다.

1. slice() 함수 사용

let originalArray = [1, 2, { a: 3, b: 4 }];
let shallowCopy = originalArray.slice();

shallowCopy[2].a = 99; // 내부 객체를 변경하면 원본에도 영향을 미침

console.log(originalArray); // [1, 2, { a: 99, b: 4 }]
console.log(shallowCopy);   // [1, 2, { a: 99, b: 4 }]

2. concat() 함수 사용

let originalArray = [1, 2, { a: 3, b: 4 }];
let shallowCopy = [].concat(originalArray);

shallowCopy[2].a = 99; // 내부 객체를 변경하면 원본에도 영향을 미침

console.log(originalArray); // [1, 2, { a: 99, b: 4 }]
console.log(shallowCopy);   // [1, 2, { a: 99, b: 4 }]

3. 전개 연산자(…) 사용

전개 연산자를 사용하여 배열이나 객체를 확장하여 복사할 수 있습니다.

let originalArray = [1, 2, { a: 3, b: 4 }];
let shallowCopy = [...originalArray];

shallowCopy[2].a = 99; // 내부 객체를 변경하면 원본에도 영향을 미침

console.log(originalArray); // [1, 2, { a: 99, b: 4 }]
console.log(shallowCopy);   // [1, 2, { a: 99, b: 4 }]

4. Array.from() 사용

Array.from() 메서드를 사용하여 배열을 복사할 수 있습니다.

let originalArray = [1, 2, { a: 3, b: 4 }];
let deepCopy = Array.from(originalArray);

deepCopy[2].a = 99; // 내부 객체를 변경하면 원본에 영향을 미침

console.log(originalArray); // [1, 2, { a: 99, b: 4 }]
console.log(deepCopy);       // [1, 2, { a: 99, b: 4 }]

깊은 복사(Deep Copy)

깊은 복사원본 객체와 완전히 독립적인 새로운 객체를 생성합니다. 내부 객체들도 재귀적으로 복사되어 내부 객체의 변경이 원본에 영향을 미치지 않습니다.

자바스크립트의 깊은 복사는 파이썬의 깊은 복사에 비해 방법이 복잡합니다.

1. JSON 함수 사용

let originalArray = [1, 2, { a: 3, b: 4 }];
let deepCopy = JSON.parse(JSON.stringify(originalArray));

deepCopy[2].a = 99; // 내부 객체를 변경해도 원본에 영향을 미치지 않음

console.log(originalArray); // [1, 2, { a: 3, b: 4 }]
console.log(deepCopy);       // [1, 2, { a: 99, b: 4 }]

참고하면 좋은 글

Leave a Comment

목차