1. 자료구조란?
밀접하게 관련된 상태나 행동을 묶어서 객체로 표현합니다.
이떄 (이름, 나이, 성별) 같은 상태와 (말한다, 먹는다) 같은 행동을 묶어놓은 사람이라는 템플릿을 만들 수 있었습니다.
클래스나 생성자 함수를 이용해서 템플릿을 잘 만들어두면 철수, 영희같은 실질 데이터가 들어있는 사람을 만들 수 있었습니다.
이렇게 클래스를 통해 만들어진 것을 인스턴스라고 했습니다. 이렇게 밀접한 정보와 행동들을 묶어서 객체로 만들 수 있습니다.
이렇게 여러 개의 객체를 특정한 자료구조에 담아둘 수 있습니다. 예를 들면, 어떤 사람들이 집합체를 만들 수 있겠죠. 그래서 사람을 모아놓은 집합체를 어떻게 나타낼 수 있을지 또는 줄을 서서 기다리는 사람도 나타낼 수 있어요. 서버에서 클라이언트에게 들어온 요청을 큐 형태로 보관해서 먼저 들어온 요청을 먼저 처리할 수 있도록 만들 수 있겠죠.
2. Array(배열)
배열의 특징
- index를 기반으로 필요한 데이터를 저장
순서가 중요중복 가능- cf. MDN Array
2.1 배열 생성 방법
1let array = new Array(3) // 3개의 사이즈를 가진 빈 배열 생성2console.log(array) // [ <3 empty items> ]34array = new Array(1, 2, 3) // 3개의 아이템을 가진 배열 생성5console.log(array) // [ 1, 2, 3 ]67array = Array.of(1, 2, 3, 4, 5) // of 함수로 배열 생성8console.log(array) // [ 1, 2, 3, 4, 5 ]910const anotherArray = [1, 2, 3, 4] // 리터럴을 이용해 배열 생성11console.log(anotherArray) // [ 1, 2, 3, 4 ]1213array = Array.from(anotherArray) // 기존의 배열에서 새로운 배열을 생성14console.log(array) // [ 1, 2, 3, 4 ]1516// 일반적으로 배열은 동일한 메모리 크기를 가지며, 연속적으로 이어져 있어함17// 하지만 자바스크립트에서의 배열은 연속적으로 이어져 있지 않고, 오브젝트와 유사함!18// 자바스크립트의 배열은 일반적인 배열의 동작을 흉내낸 특수한 객체다!19// 이걸 보완하기 위해서 타입이 정해져 있는 타입 배열이 있음 (Typed Collections)20array = Array.from({21// 오브젝트로 배열 생성220: '안',231: '녕',24length: 2,25})26console.log(array) // [ '안', '녕' ]
2.2 하면 안되는 것
1const fruits = ['🍌', '🍎', '🍇', '🍑']23// 배열 아이템을 참조하는 방법4console.log(fruits[0])5console.log(fruits[1])6console.log(fruits[2])7console.log(fruits[3])8console.log(fruits.length) // 4910// for문으로 배열 아이템 참조하는 방법11for (let i = 0; i < fruits.length; i++) {12console.log(fruits[i]) // 🍌, 🍎, 🍇, 🍑13}1415// const fruits = ['🍌', '🍎', '🍇', '🍑'];16// 추가, 삭제 - 좋지 않은 방식 💩, 참고용17// 인덱스로 바로 접근해서 추가하는 것은 좋은 방식이 아님18// 추가하려면 아래 방식을 사용19// fruits[fruits.length] = '🍓';20fruits[6] = '🍓'21console.log(fruits) // [ '🍌', '🍎', '🍇', '🍑', <2 empty items>, '🍓' ]2223// 동일한 원리로 인덱스로 바로 접근해서 삭제하는 것은 좋은 방식이 아님24delete fruits[1]25console.log(fruits) // [ '🍌', <1 empty item>, '🍇', '🍑', <2 empty items>, '🍓' ]
2.3 사용할 수 있는 함수⭐
isArray: 특정한 오브젝트가 배열인지 체크, MDN Array.isArray()indexOf: 특정한 아이템의 위치를 찾을때, MDN Array.prototype.indexOf()includes: 배열안에 특정한 아이템이 있는지 체크, MDN Array.prototype.includes()push: 추가 - 제일 뒤, MDN Array.prototype.push()unshift: 추가 - 제일 앞, MDN Array.prototype.unshift()pop: 제거 - 제일 뒤, MDN Array.prototype.pop()shift: 제거 - 제일 앞, MDN Array.prototype.shift()splice(붙이다): 중간에 추가 또는 삭제, MDN Array.prototype.splice()slice: 잘라진 새로운 배열을 만듬, MDN Array.prototype.slice()concat: 여러개의 배열을 붙여줌, MDN Array.prototype.concat()reverse: 순서를 거꾸로, MDN Array.prototype.reverse()flat: 중첩 배열을 하나의 배열로 쫙 펴기, MDN Array.prototype.flat()fill: 특정한 값으로 배열을 채우기, MDN Array.prototype.fill()join: 배열을 문자열로 합하기, MDN Array.prototype.join()
1// 배열의 함수들2// 배열 자체를 변경하는지, 새로운 배열을 반환하는지3const fruits = ['🍌', '🍎', '🍋']45// 1. 특정한 오브젝트가 배열인지 체크6console.log(Array.isArray(fruits)) // true7console.log(Array.isArray({})) // false89// 2. 특정한 아이템의 위치를 찾을때10console.log(fruits.indexOf('🍎')) // 11112// 3. 배열안에 특정한 아이팀이 있는지 체크13console.log(fruits.includes('🍎')) // true1415// 4. 추가 - 제일 뒤16let length = fruits.push('🍑') // 배열 자체를 수정(업데이트)17console.log(fruits) // [ '🍌', '🍎', '🍋', '🍑' ]18console.log(length) // 41920// 5. 추가 - 제일 앞21length = fruits.unshift('🍓') // 배열 자체를 수정(업데이트)22console.log(fruits) // [ '🍓', '🍌', '🍎', '🍋', '🍑' ]23console.log(length) // 52425// 6. 제거 - 제일 뒤26let lastItem = fruits.pop() // 배열 자체를 수정(업데이트)27console.log(fruits) // [ '🍓', '🍌', '🍎', '🍋' ]28console.log(lastItem) // 🍑2930// 7. 제거 - 제일 앞31lastItem = fruits.shift() // 배열 자체를 수정(업데이트)32console.log(fruits) // [ '🍌', '🍎', '🍋' ]33console.log(lastItem) // 🍓3435// 8. 중간에 추가 또는 삭제, splice = 붙이다36const deleted = fruits.splice(1, 1) // 1번 인덱스에 1개를 삭제37console.log(fruits) // 배열 자체를 수정(업데이트), [ '🍌', '🍋' ]38console.log(deleted) // [ '🍎' ]39fruits.splice(1, 1, '🍎', '🍓') // 1번 인덱스에 1개를 삭제하고, '🍎', '🍓'를 추가40console.log(fruits) // 배열 자체를 수정(업데이트), [ '🍌', '🍎', '🍓' ]4142// 9. 잘라진 새로운 배열을 만듬, slice = 자르다43let newArr = fruits.slice(0, 2) // 0번에서 2번 인덱스 이전까지 잘라서 새 배열 생성44console.log(newArr) // [ '🍌', '🍎' ]45console.log(fruits) // [ '🍌', '🍎', '🍓' ]46newArr = fruits.slice(-1) // 뒤에서 부터 자르기47console.log(newArr) // [ '🍓' ]4849// 10. 여러개의 배열을 붙여줌, concatenate = 연결하다50const arr1 = [1, 2, 3]51const arr2 = [4, 5, 6]52const arr3 = arr1.concat(arr2)53console.log(arr1)54console.log(arr2)55console.log(arr3) // [ 1, 2, 3, 4, 5, 6 ]5657// 11. 순서를 거꾸로58const arr4 = arr3.reverse()59console.log(arr4) // [ 6, 5, 4, 3, 2, 1 ]60console.clear()6162// 12. 1단계까지만 중첩 배열을 하나의 배열로 쫙 펴기, flat = 평평한63let arr = [64[1, 2, 3],65[4, [5, 6, [3, 4]]],66]67console.log(arr) // [ [ 1, 2, 3 ], [ 4, [ 5, 6, [Array] ] ] ]68console.log(arr.flat(3)) // [ 1, 2, 3, 4, 5, 6, 3, 4 ]69arr = arr.flat(3)7071// 13. 특정한 값으로 배열을 채우기, fill = 채우다72arr.fill(0) // 배열 자체를 모두 0으로 수정73console.log(arr) // [0, 0, 0, 0, 0, 0, 0, 0]7475arr.fill('s', 1, 3) // 1번 인덱스부터 3번 인덱스 이전까지 s로 채우기76console.log(arr) // [0, 's', 's', 0, 0, 0, 0, 0]7778arr.fill('a', 1) // 1번 인덱스부터 끝까지 a로 채우기79console.log(arr) // [0, 'a', 'a', 'a', 'a', 'a', 'a', 'a']8081// 14. 배열을 문자열로 합하기, join = 합치다82let text = arr.join()83console.log(text) // 0,a,a,a,a,a,a,a84text = arr.join(' | ')85console.log(text) // 0 | a | a | a | a | a | a | a
2.4 얕은 복사(Shallow Copy)
1// 얕은 복사(Shallow Copy) - 객체는 메모리 주소 전달2// 자바스크립트에서 복사할때는 항상 얕은 복사가 이루어짐!3// Array.from, concat, slice, spread(...), Object.assign4// 오브젝트(객체) 생성5const pizza = { name: '🍕', price: 2, owner: { name: 'Ellie' } }6const ramen = { name: '🍜', price: 3 }7const sushi = { name: '🍣', price: 1 }89const store1 = [pizza, ramen] // 배열 생성10const store2 = Array.from(store1) // 새로운 배열 생성11console.log('store1', store1)12// store1[({ name: '🍕', price: 2, owner: { name: 'Ellie' } }, { name: '🍜', price: 3 })]13console.log('store2', store2)14// store2[({ name: '🍕', price: 2, owner: { name: 'Ellie' } }, { name: '🍜', price: 3 })]1516store2.push(sushi)17console.log('store1', store1)18// store1 [19// { name: '🍕', price: 2, owner: { name: 'Ellie' } },20// { name: '🍜', price: 3 }21// ]22console.log('store2', store2)23// store2 [24// { name: '🍕', price: 2, owner: { name: 'Ellie' } },25// { name: '🍜', price: 3 },26// { name: '🍣', price: 1 }27// ]2829// 피자의 가격을 4로 인상하면서 배열을 수정하지 않아도, 피자의 가격이 변경됨30// 얕은 복사(Shallow Copy) - 객체는 메모리 주소 전달31pizza.price = 432console.log('store1', store1)33// store1 [34// { name: '🍕', price: 4, owner: { name: 'Ellie' } },35// { name: '🍜', price: 3 }36// ]37console.log('store2', store2)38// store2 [39// { name: '🍕', price: 4, owner: { name: 'Ellie' } },40// { name: '🍜', price: 3 },41// { name: '🍣', price: 1 }42// ]
3. Set
Set는 데이터의 집합체라고 볼 수 있습니다. 순서도 없고, 중복도 불가능합니다.
size: 사이즈 확인has(): 존재하는지 확인forEach(): 순회add(): 추가delete(): 삭제clear(): 전부 삭제- cf. MDN Set
1// Set : 데이터의 집합체, 인덱스 X, 중복X2const set = new Set([1, 2, 3])3console.log(set) // Set(3) { 1, 2, 3 }45// 1. 사이즈 확인6console.log(set.size) // 378// 2. 존재하는지 확인9console.log(set.has(2)) // true10console.log(set.has(6)) // false1112// 3. 순회13set.forEach(item => console.log(item)) // 1, 2, 314for (const value of set.values()) {15console.log(value) // 1, 2, 316}1718// 4. 추가19set.add(6)20console.log(set) // Set(4) { 1, 2, 3, 6 }21set.add(6)22console.log(set) // Set(4) { 1, 2, 3, 6 }, 중복 X2324// 5. 삭제25set.delete(6)26console.log(set) // Set(3) { 1, 2, 3 }2728// 6. 전부 삭제29set.clear()30console.log(set) // Set(0) {}
4. Map
Map은 [키, 값]형태로 이루어진 자료구조라고 생각하면 됩니다.
Map은 순서가 중요하지 않습니다. 다만, Key는 유일해야 합니다. 그래서 Key만 다르다면 중복이 가능합니다.
size: 사이즈 확인has(): 존재하는지 확인forEach(): 순회get(): 찾기set(): 추가delete(): 삭제clear(): 전부삭제
1const map = new Map([2['key1', '🍎'],3['key2', '🍌'],4])5console.log(map) // Map(2) { 'key1' => '🍎', 'key2' => '🍌' }67// 1. 사이즈 확인8console.log(map.size) // 2910// 2. 존재하는지 확인11console.log(map.has('key1')) // true12console.log(map.has('key6')) // false1314// 3. 순회15map.forEach((value, key) => console.log(key, value)) // key1 🍎, key2 🍌16console.log(map.keys()) // [Map Iterator] { 'key1', 'key2' }17console.log(map.values()) // [Map Iterator] { '🍎', '🍌' }18console.log(map.entries()) // [Map Entries] { [ 'key1', '🍎' ], [ 'key2', '🍌' ] }1920// 4. 찾기21console.log(map.get('key1')) // 🍎22console.log(map.get('key2')) // 🍌23console.log(map.get('key4')) // undefined2425// 5. 추가26map.set('key3', '🥝')27console.log(map) // Map(3) { 'key1' => '🍎', 'key2' => '🍌', 'key3' => '🥝' }2829// 6. 삭제30map.delete('key3')31console.log(map) // Map(2) { 'key1' => '🍎', 'key2' => '🍌' }3233// 7. 전부삭제34map.clear()35console.log(map) // Map(0) {}
Object도 [키, 값]으로 이루어져 있습니다. 그래서 Object를 Map처럼 사용할 수 있고, Map을 Object처럼 사용할 수 있습니다.
1// 오브젝트와의 큰 차이점?? 사용할 수 있는 함수가 다름, Map키에 직접 접근 불가(get사용해야 함)2const key = { name: 'milk', price: 10 }3const milk = { name: 'milk', price: 10, description: '맛있는우유' }45// 1) 오브젝트를 사용6const obj = {7[key]: milk,8}9console.log(obj)10// Map(0) {} {11// '[object Object]': { name: 'milk', price: 10, description: '맛있는우유' }12// }1314// 2) Map을 사용15const map2 = new Map([[key, milk]])16console.log(map2)17// Map(1) {18// { name: 'milk', price: 10 } => { name: 'milk', price: 10, description: '맛있는우유' }19// }2021console.log(obj[key]) // { name: 'milk', price: 10, description: '맛있는우유' }22console.log(map2[key]) // undefined, 키에 직접 접근 불가능, get 사용해야 함23console.log(map2.get(key)) // { name: 'milk', price: 10, description: '맛있는우유' }