Before Start
Data의 type에는 primitive와 object이 있다. 지금부터 살펴볼 Array의 data type은 object이다. 즉 Array는 다양한 Data를 하나로 묶어 보관하는 복합데이터라는 뜻이다. 그런 의미(복합데이터)에서 함수도 object라고 할 수 있는 것이다.
지금부터는 Array가 data type으로써가 아니라, 데이터 구조(data structure)로써 어떤 의미를 갖는지 알아볼 것이다. data type과 data structure는 다른 개념이다. data type이 단일 데이터인지, 복합데이터인지에 따라 primitive와 object로 나누어졌다면, data structure는 object(복합 데이터)를 어떻게 collect 했느냐에 따라 나누어진다. 자세한 정의를 살펴보면, data structure는 여러 개의 data와, 그 data 사이의 관계와, 그 data에 실행할 수 있는 함수의 집합을 뜻한다. Array는 이러한 자료 구조 중 하나로, 0부터 시작하는 index를 바탕으로 데이터 간의 '순서'를 중요하게 생각하는 데이터 집합이다.
How to create Array?
- Array literal
- let array = [1, 2, 3]
- 가장 흔하게 사용되는 방식이다.
- Constructor function
- array = new Array(1, 2, 3) // [1, 2, 3]
- 생성자 함수는 object를 반환하는 함수이고, JS에 기본적으로 내장된 Array class를 이용하면 새로운 배열을 반환할 수 있다.
- Class's Static function
- array = Array.of(1, 2, 3) // [1, 2, 3]
- 인자로 받은 값으로 이루어진 array를 반환한다.
- new Array()와 Array.of()의 차이점에 대해서
- array = Array.of(1, 2, 3) // [1, 2, 3]
- array = Array.from(iterable)
- Array.from()은 argument로 iterable object를 받아, shallow copied(copy by reference)된 array를 반환한다.
- iterable에 대해서는 다음 파트에서 자세히 다루어 본다. iterable object에는 string도 포함이 되는데, 만약 new Array.from('hi')라고 작성하면, ['h', 'i']를 반환한다.
Array as a data structure
Data 사이의 관계
배열은 자주 사용되는 자료 구조의 하나로, 보통의 프로그래밍 언어에서 배열의 data들은 1) 서로 동일한 type이고, 2) 중복된 값을 갖는 것이 가능하며, 3) 0부터 시작하는 index를 이용해 순서를 갖는다. 이 data들은 동일한 크기의 메모리에, 연속적으로 저장된다.
하지만 JS에서 배열은 이러한 배열의 특징을 보장해 주지는 않는다. 다른 type의 데이터를 하나의 배열 안에 집어 넣을 수 있고, 이런 데이터들이 항상 연속적으로 저장되어 있는 것도 아니다. 그렇기 때문에 JS에서 Array는 object와 아주 유사한 성질을 갖는다. 이것을 보완하기 위해 EcmaScript 2015에서 Typed Array(data의 type을 정해 둔 배열)가 새롭게 추가되었다.
Data에 자주 사용되는 functions
먼저, 아래에 정리할 함수들은 모두 array라는 자료 구조에서 사용되는 method이므로 object에서는 사용할 수 없다.
method를 사용할 때 중점적으로 살펴보아야 하는 것은 method의 실행결과이다. 특히 method를 실행했을 때 실행 대상인 배열을 "update"(수정)하는 것인지, 새로운 배열을 "create"(생성)하는 것인지를 항상 확인해야 한다.
let array = ['🍑', '🍊', '🍏', '🍇'];
- Array.isArray(value) | 인자로 전달된 value가 array인지 아닌지를 boolean 값을 반환한다.
- object를 전달하면 false를 반환한다.
- array.includes('🍔') | 인자로 전달된 value가 array의 value로 포함되어 있는지, 아닌지를 boolean 값으로 반환한다.
- array.indexOf('🍑') | 인자로 전달된 value가 위치하고 있는 index를 반환한다. 존재하지 않는 value라면 -1을 반환한다. // 0
- item 추가하기
- array.push('🍎') | UPDATE, 인자로 전달된 value가 array의 가장 마지막 index에 추가된다. // 5(new length)
- array.unshift('🍌') | UPDATE, 인자로 전달된 value가 array의 가장 첫번째 index에 추가된다. // new length
- item 삭제하기
- array.pop() | UPDATE, array의 가장 마지막 index의 item을 삭제한다. // 🍇(removed item)
- array.shift() | UPDATE, array의 가장 첫번째 index의 item을 삭제한다. // removed item
- item을 한번에 삭제, 추가하기
- array.splice(1, 0, '🍎, '🍉') | UPDATE, Index 1에서부터 0개의 item을 삭제하고 사과와 수박을 추가한다.
- // ['🍑', '🍊', '🍎, '🍉','🍏', '🍇']
- array.splice(startIndex, deleteCount, addItems...)
- item의 value를 수정하기
- array.fill('🍒', 1, 3) | UPDATE, stard에서 (end-1)-마지막 index는 불포함-까지의 아이템을 value로 바꾼다.
- // ['🍑', '🍒','🍒' '🍇']
- array.fill(value, startIndex, endIndex)
- array의 일부분 자르기
- array.slice(1, 3) | CREATE, start에서 end-1까지의 아이템을 값으로 갖는 새로운 Array를 만든다.
- // ['🍊','🍏'];
- array.slice(start, end)
- 여러개의 array를 하나로 합치기
- array.concat(array1, array2...) | CREATE
- // [1, 2, 3].concat([4, 5, 6]) => [1, 2, 3, 4, 5, 6]
- 새로운 배열을 반환하기 때문에, push 대신 사용할 수 있다.
- item의 순서를 거꾸로 만들기
- array.reverse() | UPDATE
- // ['🍇', '🍏', '🍊', '🍑']
- array의 모든 아이템을 하나의 문자열로 반환하기
- array.join(' | ') | CREATE string
- // '🍑 | 🍊 | 🍏 | 🍇'
- array.join(seperator)
- item이 iterable일 때 이를 밖으로 꺼내기
- nested.flat(1) | CREATE // [ 1, 2, 3, 4, 5, [ 6, 7 ] ]
- nested.flat(2) | CREATE // [ 1, 2, 3, 4, 5, 6, 7 ]
- array.flat(depth)
let nested = [ [1, 2, 3], [ 4, 5, [6, 7] ] ];
Array Data에 자주 사용되는 고차 함수
각 item에 콜백함수 실행하기
array = ['🍎', '🍋', '🍇', '🥝'];
- array의 각 item에 함수 실행하기
- array.forEach( (item)=> console.log(item) ) | 각 item이 순서대로 console에 출력된다.
- // 🍎 🍋 🍇 🥝
- array.forEach( (value, index, array) => { /* code to execute... */ } )
- array의 각 item에 함수를 실행하고, 그 함수의 반환값들을 요소로 하는 새로운 배열 반환
- array.map( (item) => item + '!' ) | CREATE, 각 item에 느낌표를 붙여서 새로운 item을 만들고, 새로운 item으로 구성된 배열을 반환한다.
- // [ '🍎!', '🍋!', '🍇!', '🥝!' ]
- array.map( (value, index, array) => { /* code to execute... */ } )
- ✔ 배열의 아이템이 객체일 때 주의사항
const puppies = [{name: '초코', fav:'간식'}, {name: '멍멍', fav:'장난감'}];
const fav = puppies.map(puppy => puppy.fav = '산책');
// fav = ['산책', '산책']
const newPuppies = puppies.map(puppy => {
puppy.fav = '산책';
return puppy; // here!
})
// newPuppies = [{name: '초코', fav:'산책'}, {name: '멍멍', fav:'산책'}]
let numbers = [1, 2, 3, 4, 5];
numbers.reduce( (sum, item) => sum+item, 0 ); // initial value✅
numbers.reduce( (min, item) => { // initial value❌
if(min-item > 0) {
return item; }
return min;
});
- array의 각 item에 함수를 실행. 단, 다음 item에 함수를 실행할 때 이전 item의 함수 실행 결과를 전달함 => 최종적으로는 하나의 값만 남긴다(reduce).
- sum의 초기 값으로 0이 전달되고, item의 초기 값으로는 numbers[0]이 전달된다.
- 첫번째 item에 sum + item이 실행된다(0+1 = 1) => 두번째 item에 함수를 실행할 때에는 이전의 실행결과인 1이 전달되고, 1+2가 실행된다.
- array.reduce( function(prev item, current item) { /*...*/ }, initialValue? )
각 item에 조건 검사 함수 실행하기
let apple = {name: '🍎', price: '$1' }
let lemon = {name: '🍋', price: '$2' }
let kiwi = {name:'🥝', price: '$2' }
let fruits = [apple, lemon, kiwi];
- 조건에 맞는 item이 하나라도 있는지 확인하기
- fruits.some( (item) => { return item.price === '$1' ) } | apple, lemon, kiwi item의 property 중 price의 value가 $1인 item이 있는지 확인한다.
- // true를 반환한다
- array.some( (value, index, array) => { /* code to check condition... */ } )
+) code를 {bracket}으로 감싸면 return을 명시해 주어야, 조건에 맞는 item을 반환한다. {}을 사용하지 않으면 return을 명시하지 않아도 item을 반환한다.
- 모든 item이 조건에 맞는지 확인하기
- array.every( (value, index, array) => { /* code to check condition... */ } ) | 모든 items이 조건에 맞는지 확인하고 boolean 값을 반환한다.
- 조건에 맞는 첫번째 item 반환하기
- fruits.find( (item) => item.price === '$2' ) | apple, lemon, kiwi item의 property 중 price의 value가 $2인 item을 반환한다.
- // {name: '🍋', price: '$2'}
- array.find( (value, index, array) => { /* code to check condition... */ } )
- 조건에 맞는 모든 item 반환하기
- fruits.filter( (item) => item.price === '$2' ) | CREATE, apple, lemon, kiwi item의 property 중 price의 value가 $2인 item으로 이루어진 배열을 생성한다.
- // [ {name: '🍋', price: '$2'}, {name:'🥝', price: '$2' } ]
- array.filter( (value, index, array) => { /* code to check condition... */ } )
- array에 map과 flat을 함께 실행하기
- result1 | CREATE, // [ [H,e,l,l,o], [w,o,r,l,d,!] ]
- result2 | CREATE, // [ H, e, l, l, o, w, o, r, l, d, ! ]
- array.flatMap( (value, index, array) => { /* code to execute... */ } )
- +) string.split() || array
let text = ['Hello', 'world!'];
let result1 = text.map((item) => item.split(''));
let result2 = text.flatMap((item) => item.split(''));
array = [ 5, 3, 2, 10, 1 ]
- array의 item 배열 순서 바꾸기
- array.sort() | UPDATE, 인자에 아무런 함수도 전달하지 않으면, 배열의 item 순서를 String Ascending(문자열 오름차순, a->b->c...)으로 바꾼다.
- // [ 1, 10, 2, 3, 5 ]
- array.sort( function compareFn(a, b) { /*..*/ } ) | a는 재배열하기 위해 사용되는 첫번째, b는 두번째 item이다. {bracket} 내부에서는 a와 b를 비교하는 코드를 작성하고, 코드의 return 값은 양수, 0, 음수 중 하나가 되어야 한다.
> 0 | sort a after b |
< 0 | sort a before b |
=== 0 | keep original order of a and b |
'Study > JavaScript' 카테고리의 다른 글
Iterable (0) | 2022.03.30 |
---|---|
Map & Set (0) | 2022.03.30 |
Object (0) | 2022.03.28 |
Function & Functional Programming (0) | 2022.03.26 |
Control flow statement (0) | 2022.03.25 |