다양한 객체를 특별한 구조에 담아둘 수 있다. 즉, 객체의 집합체를 나타내는 것이 자료구조이다.
자료구조종류로는 Array, Queue, Stack, Hash Table, Linked List, Tree, Graph등이 있다.
배열(Array)
배열array은 여러 개의 값(요소)을 순차적으로 나열한 자료구조다.
배열이 가지고 있는 값을 요소element라고 부른다. 자바스크립트의 모든 값은 배열의 요소가 될 수 있다. 즉, 원시값은 물론 객체, 함수, 배열 등 자바스크립트에서 값으로 인정하는 모든 것은 배열의 요소가 될 수 있다. 배열의 요소는 배열에서 자신의 위치를 나타내는 0 이상의 정수인 인덱스index를 갖는다. 인덱스는 배열의 요소에 접근할 때 사용한다.
자바스크립트에 배열이라는 타입은 존재하지 않는다. 배열은 다른 프로그래밍언어의 배열동작을 흉내낸 특수한 객체이다.
이를 보완하기위해 타입이 정해져 있는 타입배열(Typed Collecton)이 따로 존재한다.
배열 생성방법
const anotherArray = [1, 2, 3, 4]; // 배열리터럴 이용해서 배열만들기
console.log(anotherArray);
let array = new Array(2); // 생성자함수를 이용해서 배열사이즈 정하기 -> 빈칸2개의 배열이 생김
console.log(array);
array = new Array(1, 2, 3); // 생성자함수를 이용해서 지정한 요소로 배열만들기 -> 정해진 요소가 들어가있는 배열이 생김
console.log(array);
array = Array.of(1, 2); // Array의 static 메서드 이용해서 배열만들기
console.log(array);
array = Array.from(anotherArray); // Array의 static 메서드 이용해서 기존의 배열로부터 새로운 배열만들기
console.log(array);
// from의 정의: Creates an array from an iterable object.
array = Array.from('text'); '문자열도 순회가 가능하므로'
console.log(array); // [ 't', 'e', 'x', 't' ]
// 유사배열로부터 새로운 배열만들기 '유사배열도 순회가 가능하므로'
array = Array.from({
0: "안",
1: "녕",
length: 2, // 배열에는 길이라는 정보가 있다.
});
console.log(array);
일반적으로 배열은 동일한 메모리 크기를 가지며, 연속적으로 이어져 있어야 한다. 하지만 자바스크립트에서의 배열은 연속적으로 이어져 있지 않고 오브젝트와 유사한 개념에 더 가깝다.(거의 같음) 즉, 자바스크립트의 배열은 일반적인 배열의 동작을 흉내낸 특수한 객체다.
이걸 보완하기 위해서 타입이 정해져 있는 타입 배열이 있음 (Typed Collecton)
Typed Collecton목록: https://developer.mozilla.org/ko/docs/Web/JavaScript/Typed_arrays
배열(Array)의 특성
배열에 접근하는 방법
const fruits = ["🍌", "🍎", "🍇", "🍑"];
//배열에 접근하는 일반적인 방법
console.log(fruits[0]);
console.log(fruits[1]);
console.log(fruits[2]);
console.log(fruits[3]);
console.log(fruits.length); // 4
배열의 장점
const fruits = ["🍌", "🍎", "🍇", "🍑"];
for (let i = 0; i < fruits.length; i++) {
console.log(fruits[i]);
}
일반 객체와 배열을 구분하는 가장 명확한 차이는 “값의 순서존재유무”와 “length 프로퍼티”다. 인덱스로 표현되는 값의 순서와 length 프로퍼티를 갖는 배열은 반복문을 통해 순차적으로 값에 접근하기 적합한 자료구조이다. 이러한 특성때문에 배열은 처음부터 순차적으로 요소에 접근할 수도 있고, 마지막부터 역순으로 요소에 접근할 수도 있으며, 특정 위치부터 순차적으로 요소에 접근할 수도 있다는 장점이 있다.
배열의 요소를 추가, 삭제할때 좋지않은 방법들
const fruits = ['🍌', '🍎', '🍇', '🍑'];
// 배열의 요소를 추가, 삭제할때 좋지않은 방식들
fruits[6] = "🍓";
console.log(fruits);
// 만약 배열.length가 x인데, x+3이상의값에 할당하면
// x+1칸, x+2칸이 빈공간인채로 남아있기때문에 좋지 않은 방법이다.
delete fruits[1];
console.log(fruits);
// 만약 배열.length가 x(단, x>4)인데 x-2값을 삭제한다고 가정했을 때
// x-2칸이 빈공간인채로 남아있기때문에 좋지 않은 방법이다.
배열(Array)의 메서드
자바스크립트는 배열을 다룰 때 유용한 다양한 빌트인 메서드를 제공한다. 범주를 크게 2가지로 분류할 수 있다.
- Array 생성자함수의 정적 메서드
- Array.prototype메서드 (배열 객체의 프로토타입인 Array.prototype는 프로토타입 메서드를 제공한다.)
배열은 사용 빈도가 높은 자료구조이므로 배열 메서드의 사용법을 잘 알아둘 필요가 있다. 배열 메서드는 결과물을 반환하는 패턴이 두 가지이므로 주의가 필요하다. 배열에는 원본 배열(배열 메서드를 호출한 배열, 즉 배열 메서드의 구현체 내부에서 this가 가리키는 객체)을 직접 변경하는 메서드(mutatormethod)와 원본 배열을 직접 변경하지 않고 새로운 배열을 생성하여 반환하는 메서드(accessor method)가 있다.
배열 자체를 변경하는지, 새로운 배열을 반환하는지가 중요하다.
static method
const fruits = ["🍌", "🍎", "🍋"];
// 특정한 오브젝트가 배열인지 체크
console.log(Array.isArray(fruits));
console.log(Array.isArray({}));
instance method
const fruits = ["🍌", "🍎", "🍋"];
// 특정한 아이템의 위치를 찾을때
console.log(fruits.indexOf("🍎"));
const fruits = ["🍌", "🍎", "🍋"];
// 배열안에 특정한 아에팀이 있는지 체크
console.log(fruits.includes("🍎"));
const fruits = ["🍌", "🍎", "🍋"];
// 추가 - 제일 앞
length = fruits.unshift("🍓"); // 배열 자체를 수정(업데이트)
console.log(fruits);
console.log(length);
// 추가 - 제일 뒤
let length = fruits.push("🍑"); // 배열 자체를 수정(업데이트)
console.log(fruits);
console.log(length);
// 제거 - 제일 앞
lastItem = fruits.shift(); // 배열 자체를 수정(업데이트)
console.log(fruits);
console.log(lastItem);
// 제거 - 제일 뒤
let lastItem = fruits.pop(); // 배열 자체를 수정(업데이트)
console.log(fruits);
console.log(lastItem);
// 중간에 추가 또는 삭제
const deleted = fruits.splice(1, 1);
console.log(fruits); // 배열 자체를 수정(업데이트)
console.log(deleted);
fruits.splice(1, 1, "🍎", "🍓");
console.log(fruits); // 배열 자체를 수정(업데이트)
// 특정한 값으로 배열을 채우기
arr.fill(0); // 배열 자체를 수정
console.log(arr);
arr.fill("s", 1, 3); // end-index는 미만의 개념임 -> end-index가 3이면 3제외 2까지
console.log(arr);
arr.fill("a", 1); // end-index를 작성하지않으면 시작단계에서 배열끝index까지 수정함
console.log(arr);
// 잘라진 새로운 배열을 만듦
let newArr = fruits.slice(0, 2); // 배열.slice(0, 2)는 배열요소의 0부터 1까지를 남기고 나머지를 slice한다는 의미이다.
console.log(newArr);
console.log(fruits);
newArr = fruits.slice(-1); // 제일 마지막요소에서 한칸앞의 요소부터 slice된다는 의미이다.
console.log(newArr);
// 여러개의 배열을 붙여서 새로운 배열을 만듦
const arr1 = [1, 2, 3];
const arr2 = [4, 5, 6];
const arr3 = arr1.concat(arr2);
console.log(arr1);
console.log(arr2);
console.log(arr3);
// 순서를 거꾸로한 새로운 배열을 만듦
const arr4 = arr3.reverse();
console.log(arr4);
console.clear();
// 중첩 배열을 하나의 배열로 쫙 핀 새로운 배열을 리턴함
let arr = [
[1, 2, 3],
[4, [5, 6, [3, 4]]],
];
console.log(arr);
console.log(arr.flat(3)); // 배열을 몇단계까지풀어줄지 정할 수 있음
arr = arr.flat(3);
// 배열을 문자열로 합하기
const arr = [1, 2, 3, 4];
let text = arr.join();
console.log(text); // '1,2,3,4';
text = arr.join("");
console.log(text); // '1234'
text = arr.join(":");
console.log(text); // '1:2:3:4'
얕은복사(Shallow Copy)
얕은 복사의 경우 객체를 온전히 받아오는 것이 아니라 참조된 값, 즉 객체의 메모리 주소를 복사하여 같은 객체를 참조한다.
// 자바스크립트에서 복사할때(배열에 기존 배열을 가져올때 등등..)는 항상 얕은 복사가 이루어짐!
// Array.from, concat, slice, spread(...), Object.assign 모두 Shollow Copy가 이루어짐
const pizza = { name: "🍕", price: 2, owner: { name: "Ellie" } };
const ramen = { name: "🍜", price: 3 };
const sushi = { name: "🍣", price: 1 };
const store1 = [pizza, ramen];
const store2 = Array.from(store1);
console.log("store1", store1);
console.log("store2", store2);
// sotre1과 store2는 완전히 다른 객체이므로 store2에 무언가를 추가한다 하더라도
// store1에는 전혀 변화가 없는 것을 확인할 수 있다.
store2.push(sushi);
console.log("store1", store1);
console.log("store2", store2);
// store1과 store2는 새롭게 배열을 만드는 것이 아니라,
// pizza와 ramen이 가지고있는 배열의 메모리주소를 참조해 배열이 저장된 곳을 찾아가,
// 저장된 배열을 가지고오기때문에 저장된 배열의 값을 바꾸면,
// 그 배열을 가지고있는 배열도 바뀐 배열의 값을 가지고 있는 것이다.
pizza.price = 4;
console.log("store1", store1);
console.log("store2", store2);
고차함수(Higher-order function)
함수를 인자로 받는 함수(콜백함수), 함수를 반환(출력)하는 함수를 고차함수라 한다.
함수형프로그래밍, 순수함수, 불변성 -> side effect가 없도록
const fruits = ["🍌", "🍓", "🍇", "🍓"];
// 반복문을 길게 작성하기 싫다면...
// 배열을 빙글 빙글 돌면서 원하는것(콜백함수)을 할때 -> 배열의 요소마다 한번씩 호출된다.
// forEach는 요소, 인덱스, 배열사이즈를 인자로 받을 수 있다.
// 아래의 예시처럼 3개의 인자를 모두 작성할필요없이 원하는 인자만 선택할 수있다.
fruits.forEach(function (value) {
console.log(value);
});
fruits.forEach((value) => console.log(value));
// 조건에 맞는(콜백함수) 아이템을 찾을때
// find: 제일 먼저 조건에 맞는 아이템을 반환
const item1 = { name: "🥛", price: 2 };
const item2 = { name: "🍪", price: 3 };
const item3 = { name: "🍙", price: 1 };
const products = [item1, item2, item3, item2];
let result = products.find((item) => item.name === "🍪");
console.log(result);
// findIndex: 제일 먼저 조건에 맞는 아이템의 인덱스를 반환
result = products.findIndex((item) => item.name === "🍪");
console.log(result);
// 배열의 아이템들이 부분적으로(하나라도) 조건(콜백함수)에 맞는지 확인
result = products.some((item) => item.name === "🍪");
console.log(result);
// 배열의 아이템들이 전부 조건(콜백함수)에 맞는지 확인
result = products.every((item) => item.name === "🍪");
console.log(result);
// 조건에 맞는 모든 아이템들을 요소로 저장한 새로운 배열을 반환
result = products.filter((item) => item.name === "🍪");
console.log(result);
console.clear();
// Map 배열의 아이템들을 각각 다른 아이템으로 매핑할 수 있는, 변환해서 새로운 배열 생성!
const nums = [1, 2, 3, 4, 5];
result = nums.map((item) => item * 2);
console.log(result);
result = nums.map((item) => {
if (item % 2 === 0) {
return item * 2;
} else {
return item;
}
});
console.log(result);
// Flatmap: 중첩된 배열을 쫘악 펴서 새로운 배열로!
result = nums.map((item) => [1, 2]);
console.log(result);
result = nums.flatMap((item) => [1, 2]);
console.log(result);
result = ["dream", "coding"].map((text) => text.split(""));
console.log(result);
result = ["dream", "coding"].flatMap((text) => text.split(""));
console.log(result);
// sort 배열의 아이템들을 정렬
// 문자열 형태의 오름차순으로 요소를 정렬하고
// 기존의 배열을 변경
const texts = ["hi", "abc"];
texts.sort();
console.log(texts);
// 숫자를 문자열로 변환하여 정렬하기때문에 10중 1을 먼저 detecting해서 10이 2보다 앞서 정렬된다.
const numbers = [0, 5, 4, 2, 1, 10];
numbers.sort();
console.log(numbers);
// < 0 a가 앞으로 정렬, 오름차순
// > 0 b가 앞으로 정렬, 내림차순
numbers.sort((a, b) => a - b);
console.log(numbers);
// reduce 배열의 요소들을 접어서 접어서 값을 하나로!
result = [1, 2, 3, 4, 5].reduce((sum, value) => {
sum += value;
return sum;
}, 0);
// 같은거임
result = [1, 2, 3, 4, 5].reduce((sum, value) => (sum += value), 0);
console.log(result);
'자바스크립트 개념정리' 카테고리의 다른 글
Set&Map (0) | 2022.12.04 |
---|---|
Iterator&Generator (0) | 2022.12.02 |
내장객체(Built-in Objects) (0) | 2022.11.28 |
클래스(Class) (0) | 2022.11.27 |
객체(object) (0) | 2022.11.20 |