이번에는 자바스크립트의 대표적인 기본 데이터인 배열에 대해서 알아보고,
배열 객체 내장 함수에 대해서 설명과 예시를 들어서 자세히 살펴보겠습니다.
배열은 복수의 데이터를 다룰 때 사용합니다.
배열은 데이터를 담을 때 순서가 있는 나열 방식을 이용하는 자료구조 입니다.
배열을 선언하는 방법은 2가지가 있습니다.
let arr1 = new Array();
let arr2 = []; // 대부분 이 방법으로 배열을 선언함.
배열은 어떠한 데이터 타입도 담을 수 있습니다.
let nums = [1, 2, 3];
let str = ['1', '2', '3'];
let mix = [1, '2', true, [], {}];
각 배열 요소는 0부터 시작하는 순번이 정해져 있습니다.
이 순번인 인덱스 번호를 이용해서 배열의 특정한 요소에 접근할 수 있습니다.
let subject = ['국어', '수학', '영어'];
console.log(subject[0]); // '국어'
console.log(subject[1]); // '수학'
console.log(subject[2]); // '영어'
인덱스 번호를 이용해서 배열 요소를 수정도 할 수 있습니다.
subject[0] = '역사';
console.log(subject[0]); // '역사'
length를 이용하면 배열의 요소 개수를 알 수 있습니다.
length는 배열의 길이를 숫자 타입으로 반환해 줍니다.
console.log(subject.length); // 3
배열은 대괄호([]) 외에도 new Array()로 선언할 수 있습니다.
const array = new Array('하나', '둘');
console.log(array[0]); // '하나'
console.log(array[1]); // '둘'
console.log(array.length); // 2
new Array()의 소괄호 안에 숫자를 넣으면 배열의 길이를 초기에 설정할 수 있습니다.
const array2 = new Array(10);
console.log(array2); // (10) [비어 있음 × 10]
array2[9] = '끝';
console.log(array2); // (10) [비어 있음 × 9, '끝']
이제 배열의 메서드(함수)에 대해서 알아보겠습니다.
push는 배열의 맨 끝에 요소를 추가하는 함수입니다.
그리고 요소를 추가한 후 배열의 길이를 숫자 타입으로 반환해 줍니다.
let color = ['red', 'green', 'blue'];
color.push('pink'); // 4
console.log(color); // (4) ['red', 'green', 'blue', 'pink']
pop()은 맨 끝 요소를 추출합니다.
pop()은 추출한 요소를 반환해 줍니다.
color.pop(); // 'pink'
console.log(color); // (3) ['red', 'green', 'blue']
unshift()는 push()와 반대로 맨 앞에 요소를 추가합니다.
unshift()도 요소를 추가한 후 배열의 길이를 숫자 타입으로 반환합니다.
let color = ['red', 'green', 'blue'];
color.unshift('black'); // 4
console.log(color); // (4) ['black', 'red', 'green', 'blue']
shift()는 pop()과 반대로 맨 앞의 요소를 추출합니다.
그리고 추출한 요소를 반환해 줍니다.
color.shift(); // 'black'
console.log(color); // (3) ['red', 'green', 'blue']
여러 개의 배열을 하나로 만들고 싶을 때 사용합니다.
const nums = ['1️⃣', '2️⃣', '3️⃣'];
const emotions = ['😀', '😁'];
const newArr = nums.concat(emotions);
console.log(newArr); // (5) ['1️⃣', '2️⃣', '3️⃣', '😀', '😁']
전개(spread) 연산자 (...)를 사용해서 [...배열] 형태로 배열을 선언하면 배열 요소의 데이터가 전부 들어간 배열을 만들 수 있습니다.
const nums = ['1️⃣', '2️⃣', '3️⃣'];
const emotions = ['😀', '😁'];
const newArr = [...nums, ...emotions];
console.log(newArr); // (5) ['1️⃣', '2️⃣', '3️⃣', '😀', '😁']
결과는 concat 메서드를 사용한 것과 같습니다.😀
배열의 요소를 지우거나 추가할 때 사용할 수 있습니다.
문법은 아래와 같습니다. [ ] 안에는 들어가도, 안들어가도 되는 인자입니다.
// 문법
배열.splcie(인덱스[, 삭제개수, 요소1, 요소2, ... 요소N]);
삭제와 추가는 아래와 같습니다.
splice()로 삭제를 하면 원본 배열이 변형됩니다.
❗ 특이한건 음수 인덱스를 사용할 수 있다는 것입니다.
// 삭제
let fruits = ['🍉','🍊','🍋','🍇','🍌'];
fruits.splice(1, 1); // ['🍊']
// console.log(fruits); // (4) ['🍉', '🍋', '🍇', '🍌']
// 추가
fruits.splice(1, 0, '🍊');
console.log(fruits); // (5) ['🍉', '🍊', '🍋', '🍇', '🍌']
// 음수 인덱스 사용 👈
fruits.splice(-1, 1); // ['🍌']
console.log(fruits); // practice:13 (4) ['🍉', '🍊', '🍋', '🍇']
배열은 객체형에 속하기 때문에 예약어 delete로도 요소를 삭제할 수 있습니다.
하지만 delete로 배열 요소를 삭제해도 요소만 삭제되고
배열의 길이는 변하지 않습니다. 이점을 주의해서 delete 예약어를 써야합니다.
let fruits = ['🍉','🍊','🍋','🍇','🍌'];
delete fruits[0];
console.log(fruits); // (5) [비어 있음, '🍊', '🍋', '🍇', '🍌']
splice()와 유사하지만 훨씬 간단하게 쓸 수 있습니다.
slice()는 원본 배열을 변형시키지 않습니다.
// 문법
배열.slice([시작인덱스], [끝인덱스]);
❗ 끝인덱스는 포함되지 않습니다. 범위는 시작인덱스~끝인덱스-1 까지의 요소를 의미합니다.
slice()도 splice()처럼 음수 인자를 넣을 수 있습니다.
인자를 하나만 넣으면 해당 인자 인덱스 요소부터 배열 끝까지 해당합니다.
let name = ['h', 'a', 'r', 'i', 'm', 'a', 'd'];
console.log(name.slice(4)); // (3) ['m', 'a', 'd']
console.log(name.slice(4, 7)); // (3) ['m', 'a', 'd']
console.log(name.slice(-3)); // (3) ['m', 'a', 'd']
console.log(name); // (7) ['h', 'a', 'r', 'i', 'm', 'a', 'd']
배열을 순회할 때 for문은 가장 오래 사용된 방법입니다.
배열을 순회할 때 인덱스를 사용합니다.
let name = ['h', 'a', 'r', 'i', 'm', 'a', 'd'];
for (let i = 0; i < name.length<; i++) {
console.log(name[i]);
}
for와는 또 다른 방법입니다.
for...of는 현재 요소의 인덱스를 얻을 수 없고 요소 값만 얻을 수 있습니다.
배열을 반복 순회할 때 간편하게 쓸 수 있습니다.
let name = ['h', 'a', 'r', 'i', 'm', 'a', 'd'];
for (x of name) {
console.log(x);
}
배열은 객체형이기 때문에 for...in을 사용할 수 있습니다.
for...in은 현재 요소의 인덱스를 순회합니다.
배열요소를 반복순회할 때는 for...in을 사용할 수는 있지만 속도가 느리기 때문에 for...of를 쓰는게 더 좋습니다.
let name = ['h', 'a', 'r', 'i', 'm', 'a', 'd'];
for (x in name) {
console.log(name[x]);
}
forEach()는 인자로 콜백함수를 넣어서 반복작업을 할 수있습니다.
콜백함수의 item은 배열 요소를 가리킵니다.
index는 배열 요소의 인덱스를 가리키고, array는 배열 전체 요소를 가리킵니다.
let name = ['h', 'a', 'r', 'i', 'm', 'a', 'd'];
name.forEach(function (item, index, array) {
console.log(`item: ${item}, index: ${index}, array: ${array}`);
})
/*
** 실행결과
** item: h, index: 0, array: h,a,r,i,m,a,d
** item: a, index: 1, array: h,a,r,i,m,a,d
** item: r, index: 2, array: h,a,r,i,m,a,d
** item: i, index: 3, array: h,a,r,i,m,a,d
** item: m, index: 4, array: h,a,r,i,m,a,d
** item: a, index: 5, array: h,a,r,i,m,a,d
** item: d, index: 6, array: h,a,r,i,m,a,d
*/
forEach()는 예약어 continue나 break를 사용할 수 없습니다.
그리고 forEach()는 반복문을 도중에 중단할 수 없습니다.
let name = ['h', 'a', 'r', 'i', 'm', 'a', 'd'];
name.forEach(function (item, index, array) {
if (item === 'r') {
return;
}
console.log(`item: ${item}, index: ${index}, array: ${array}`);
})
/*
** 실행결과
** item: h, index: 0, array: h,a,r,i,m,a,d
** item: a, index: 1, array: h,a,r,i,m,a,d
**
** item: i, index: 3, array: h,a,r,i,m,a,d
** item: m, index: 4, array: h,a,r,i,m,a,d
** item: a, index: 5, array: h,a,r,i,m,a,d
** item: d, index: 6, array: h,a,r,i,m,a,d
*/
배열의 요소를 정렬합니다. 그리고 원본 배열이 변형됩니다.
배열.sort()만 쓴다면 문자열을 기준으로 정렬합니다.
문자열 비교는 사전편집 순으로 하기 때문에 10 보다 2가 더 큰값으로 취급합니다.
const arr = [1, 10, 2, 3];
console.log(arr.sort()); // (4) [1, 10, 2, 3]
숫자를 기준으로 오름차순 정렬하고 싶다면 sort()안에 새로운 함수(콜백함수)를 넣어줘야 합니다.
❗ 콜백함수의 인자로 2개가 들어가야하고 두 값을 비교해서 양수, 음수, 0 이 반환 되도록 해야합니다.
만약에 두 값을 비교해서 양수가 나오면 두 인자의 위치를 바꿔줍니다.
양수가 아니면 값을 바꾸지 않습니다.
const arr = [1, 10, 2, 3];
console.log(arr.sort(function(a, b) { return a - b; }))
//(4) [1, 2, 3, 10]
sort() 안의 함수 인자의 반환 값을 아래와 같이 바꾸면 내림차순 정렬이 가능합니다.
const arr = [1, 10, 2, 3];
console.log(arr.sort(function(a, b) { return b - a; }))
//(4) [10, 3, 2, 1]
map은 배열 요소 전체를 대상으로 콜백함수를 호출하는데요,
함수 호출 결과를 바탕으로 새로운 배열을 반환합니다.
콜백함수에 ietm, index, array인자는 생략이 가능합니다.
const nums = [1, 10, 100, 2, 20, 200];
const newNums = nums.map(function(item, index, array) {
console.log(`item: ${item}, index: ${index}, array: ${array}`);
return item*100;
});
/* 실행결과
** item: 1, index: 0, array: 1,10,100,2,20,200
** item: 10, index: 1, array: 1,10,100,2,20,200
** item: 100, index: 2, array: 1,10,100,2,20,200
** item: 2, index: 3, array: 1,10,100,2,20,200
** item: 20, index: 4, array: 1,10,100,2,20,200
** item: 200, index: 5, array: 1,10,100,2,20,200
*/
console.log(newNums); // (6) [100, 1000, 10000, 200, 2000, 20000]
filter는 map과 비슷하게 배열 요소 전체를 대상으로 콜백함수를 호출합니다.
콜백함수의 반환값이 true인 값을 새 배열에 담아서 반환합니다.
const nums = [1, 10, 100, 2, 20, 200];
const newNums = nums.filter(function(item, index, array) {
console.log(`item: ${item}, index: ${index}, array: ${array}`);
return item > 100;
});
/* 실행결과
** item: 1, index: 0, array: 1,10,100,2,20,200
** item: 10, index: 1, array: 1,10,100,2,20,200
** item: 100, index: 2, array: 1,10,100,2,20,200
** item: 2, index: 3, array: 1,10,100,2,20,200
** item: 20, index: 4, array: 1,10,100,2,20,200
** item: 200, index: 5, array: 1,10,100,2,20,200
*/
console.log(newNums); // (1) [200]
reduce()는 배열 요소를 하나의 값으로 만들고 싶을 때 사용합니다.
문법은 아래와 같습니다.
// 문법
let newValue = arr.reduce(function(accumulator, currentItem, index, array) {
// ...
}, [initial])
reduce()의 인자로 콜백함수와 초기값이 들어갑니다. 초기값은 생략가능합니다.
reduce()를 이용해서 배열의 요소 합계를 구해보면 아래와 같습니다.
실행 흐름을 보면 첫 acc는 initial 값이 들어갑니다.
acc + curr 된 값이 다음 실행할 때 acc의 값으로 들어갑니다.
curr은 배열의 인자값이 하나씩 들어가서 배열 요소 끝이 나올 때 까지 reduce()가 실행됩니다.
const arr = [10, 20, 30, 40, 50];
let value = arr.reduce(function(acc, curr) {
return acc + curr
}, 0);
console.log(value); // 150
/*
** 실행 흐름
** acc : 0 , curr : 10 result : 10
** acc : 10 , curr : 20 result : 30
** acc : 30 , curr : 30 result : 60
** acc : 60 , curr : 40 result : 100
** acc : 100, curr : 50 result : 150
*/
배열 요소를 역순으로 정렬시키는 메서드 입니다.
새로 정렬된 배열을 반환합니다
const nums = [1, 2, 3];
console.log(nums.reverse()); // (3) [3, 2, 1]
배열 안의 요소를 결합할 때 사용합니다.
결합할문자열은 생략이 가능합니다.
// 문법
배열.join([결합할문자열])
공백을 넣으면 자동으로 쉼표로 동작합니다.
const array = ['h','e','l','l','o'];
console.log(array.join()); // h,e,l,l,o
console.log(array.join(',')); // h,e,l,l,o
console.log(array.join('+')); // h+e+l+l+o
배열 안의 모든 문자를 쉼표(,)로 구분해서 하나의 문자열로 반환시켜줍니다.
const fruits = ['🍉', '🍋', '🍊', '🍌'];
console.log(fruits.toString()); // 🍉,🍋,🍊,🍌
indexOf와 lastIndexOf와 includes는 같이 보겠습니다.
// 문법
// 시작할 위치는 생략이 가능합니다.
배열.indexOf(검색할데이터, [시작할위치])
배열.lastIndexOf(검색할데이터, [시작할위치])
배열.includes(검색할데이터, [시작할위치])
indexOf와 lastIndexOf의 실행결과 검색할 데이터가 배열에 없으면 -1을 반환합니다.
만약 검색할 데이터를 발견한다면 해당 인덱스를 반환합니다.
includes는 검색할 데이터가 있으면 true를 반환하고 그렇지 않다면 false를 반환합니다.
[1, 2, 3, 4, 5, 1, 2, 3].indexOf(2); // 1
[1, 2, 3, 4, 5, 1, 2, 3].indexOf(2, 4); // 6
[1, 2, 3, 4, 5, 1, 2, 3].lastIndexOf(2); // 6
[1, 2, 3, 4, 5].lastIndexOf(2); // 1
[1, 2, 3, 4, 5].includes(2); // true
[1, 2, 3, 4, 5].includes(10); // false
문법은 아래와 같습니다. find와 findIndex의 사용법은 비슷합니다.
// 문법
배열.find(function(item, index, array) {
return 조건
});
find는 조건에 맞는 해당 요소를 반환합니다.
findIndex는 조건에 맞는 해당 요소의 인덱스를 반환합니다.
하지만, 조건에 맞는 요소가 없다면 -1을 반환합니다.
find(), findIndex() 의 인자로 콜백함수가 들어갑니다.
콜백함수의 인자는 배열의 요소인 item, 요소의 인덱스인 index, 배열 요소 전체를 가리키는 array가 들어갈 수 있습니다.
❗ 콜백함수의 item, index, array 인자가 생략이 가능합니다.
const fruits = ['🍇', '🍋','🍌','🍊', '🍉'];
const myFruit = fruits.find(function(item, index, array) {
console.log(`item: ${item}, index: ${index}, array: ${array}`);
return item === '🍋';
})
/* 실행결과
** item: 🍇, index: 0, array: 🍇,🍋,🍌,🍊,🍉
** item: 🍋, index: 1, array: 🍇,🍋,🍌,🍊,🍉
*/
console.log(myFruit); // 🍋
find()는 조건에 맞는 반환 값을 만나면 그 즉시 배열 요소 반복문을 종료합니다.
findIndex()도 동일합니다.
const myFruitIndex = fruits.findIndex(function(item, index, array) {
console.log(`item: ${item}, index: ${index}, array: ${array}`);
return item === '🍉';
});
/* 실행결과
** item: 🍇, index: 0, array: 🍇,🍋,🍌,🍊,🍉
** item: 🍋, index: 1, array: 🍇,🍋,🍌,🍊,🍉
** item: 🍌, index: 2, array: 🍇,🍋,🍌,🍊,🍉
** item: 🍊, index: 3, array: 🍇,🍋,🍌,🍊,🍉
** item: 🍉, index: 4, array: 🍇,🍋,🍌,🍊,🍉
*/
console.log(myFruitIndex); // 4
자바스크립트에서는 배열이 독립된 자료형이 아니라 객체형안에 속합니다.
그래서 typeof로는 객체와 배열을 구분할 수 없습니다.
이럴 때 isArray()로 배열 여부 알아낼 수 있습니다.
Array.isArray()로 인자에 값을넣어서 배열이면 true를 반환하고, 그렇지 않다면 false를 반환합니다.
console.log(typeof []); //object
console.log(typeof {}); //object
console.log(typeof null); //object
console.log(Array.isArray([])); // true
console.log(Array.isArray({})); // false
지금까지 자바스크립트에서 자주 쓰이는 대표적인 기본 데이터 타입인 배열에 대해서 알아보고 배열 객체 내장 함수들에 대해서 알아봤습니다.
이번 챕터는 글이 굉장히 길어서 한번에 다 읽지 못하실 수 있습니다.
한번에 다 읽지 않으셔도 좋습니다.
긴 호흡을 가지고 필요한 부분만 찾아서 보셔도 좋습니다.😀
메모: 대부분 기능 위주의 정리. 내장 함수 중에 실제 예시를 고민해 보기.