메모리를 효율적으로 사용하며 빠르고 안정적으로 데이터를 처리하는 것이 궁극적인 목표로
상황에 따라 유용하게 사용될 수 있도록 특정 구조를 이루고 있다.
자주 등장하는 네 가지의 자료구조 = Stack, Queue, Tree, Graph
현실에 존재하는 영화 예매를 어떻게 컴퓨터로 옮길 것인가? 무엇을 고려해야 하는가?
결국 자료구조는 일차원인 컴퓨터 메모리를 현실에 대응되도록 구조를 만든 것이라 할 수 있다.
단순 구조선형 구조비선형 구조파일구조한 원소 뒤에 하나의 원소 만이 존재하는 형태로 자료들이 선형으로 나열되어 있는 구조

원소 간 다대다 관계를 가지는 구조로 계층적 구조나 망형 구조를 표현하기에 적절

더 좋고 더 나쁜 자료구조는 없다. 특정 상황에서 유용한 자료구조와 덜 유용한 자료구조가 존재할 뿐이다.
우리는 상황에 맞는 적절한 자료구조를 선택하면 된다.
고려할 것
프로그램의 성능을 정학히 파악하는 것은 불가능합니다.
그렇기 때문에 컴퓨터 과학자들은 대략적인 성능을 파악하기 위해 빅오 표기법을 도입했습니다.

: 상수 시간❌
: 로그 시간
: 선형 시간(linear time)
: 선형 로그 시간
: 2차 시간
: 지수 시간❌
: 팩토리얼 시간❌
Ref
for (let i = 0; i < n; i += 1) {
// ...
}
for (let i = 0; i <= n; i += 2) {
// ...
}
for (let i = 0; i < n; i += 1) {
for (let j = 1; j <= n; i += 2) {
// ...
}
}
for (let i = 0; i < n; i += 1) {
for (let j = 0; j < n; i += 1) {
// ...
}
}
빅오 표기법은 점근적 표기법을 따릅니다. 점근적 표기법은 함수의 증감 추세를 비교하는 방법입니다.
다음 그림처럼 c와 g가 양수라고 가정하고, n이 를 넘어설 떄,
함수 에는 함수 에 한없이 가까워질 순 있지만, 넘을 수는 없습니다.
한마디로, 함수 g(n)에는 함수 f의 한계치라 할 수 있습니다.

// 두 루프는 같은 O(n)으로 표기된다.
for (let i = 0; i < n; i += 1) {
// ...
}
for (let i = 0; i < n * 5; i += 1) {
// ...
}
// 두 루프를 합쳐 O(n + m)으로 표기할 수 있다.
// 계수 법칙에 의해 5는 사라진다.
for (let i = 0; i < n; i += 1) {
// ...
}
for (let i = 0; i < m * 5; i += 1) {
// ...
}
// 두 루프를 곱해 O(n^2)으로 표기할 수 있다.
// 계수 법칙에 의해 5는 사라진다.
for (let i = 0; i < n; i += 1) {
for (let j = 0; j < n * 5; j += 1) {
// ...
}
}
// 다음 루프는 O(n^3)으로 표기할 수 있다.
for (let i = 0; i < n * n * n; i += 1) {
// ...
}
2가지만 기억하세요.
(1) 상수항은 무시
// 계수 법칙에 의해 계수는 무시된다.
// 그리하여 O(n + m)으로 표기된다.
for (let i = 0; i < n * 6; i += 1) {
// ...
}
for (let i = 0; i < m * 3; i += 1) {
// ...
}
(2) 가장 큰 항 외엔 무시
// O(n^2 + n)이지만 작은 항은 무시하여
// O(n^2)으로만 표기해도 된다.
for (let i = 0; i < n; i += 1) {
// ...
}
for (let i = 0; i < n; i += 1) {
for (let j = 0; j < n; j += 1) {
// ...
}
}
const start = new Date().getTime();
// ...
const end = new Date().getTime();
console.log(end - start);
console.log('start');
const start = new Date().getTime();
const N = 1000000000;
let total = 0;
for (let i = 0; i < N; i += 1) {
total += i;
}
const end = new Date().getTime();
console.log(end - start);
console.log('Finish');
/* 결과
start
1063
Finish
*/
ES6의 구조 분해 할당 문법을 사용하여 두 변수를 swap 할 수 있습니다.
let a = 5, b = 10;
[a, b] = [b, a];
console.log(a, b); // 10 5
보통 단순히 범위 루프를 돌고 싶다면 다음과 같이 코드를 작성합니다.
let sum = 0;
for (let i = 5; i < 10; i += 1) {
sum += i; // 35 (5~9까지의 합)
}
만약 범위 루프를 함수형 프로그래밍 방식으로 사용하고 싶다면 배열을 생성해서 사용할 수 있습니다.
// (_, k) => k + 5
// _는 보통 사용하지 않는 변수, 파라메터 등에 이름을 붙일 때 사용
// 특별한 문법적인 기능이 있지는 않지만 관례상 사용되는 규칙
const sum = Array
.from(new Array(5), (_, k) => k + 5) // 5부터 시작하는 유사 배열 생성
.reduce((acc, cur) => acc + cur, 0);
💡
from(): 문자열 등 유사 배열(Array-like) 객체나 이터러블한 객체를 배열로 만들어주는 메서드Array.from(복사할 배열, 복사하면서 수행할 function)
Set을 이용할 수 있습니다.
const names = ['Lee', 'Kim', 'Park', 'Lee', 'Kim'];
const uniqueNamesWithArrayFrom = Array.from(new Set(names));
const uniqueNamesWithSpread = [...new Set(names)];
두 객체를 별도 변수에 합쳐줄 수 있습니다.
const person = {
name: 'Lee Sun-Hyoup',
familyName: 'Lee',
givenName: 'Sun-Hyoup',
};
const company = {
name: 'Cobalt. Inc.',
address: 'Seoul',
};
const leeSunHyoup = { ...person, ...company };
console.log(leeSunHyoup);
// {
// name: 'Cobalt. Inc.',
// familyName: 'Lee',
// givenName: 'Sun-Hyoup',
// address: 'Seoul' 같은 키는 마지막에 대입된 값으로 정해진다.
// }
&&와 ||는 조건문 외에서도 활용될 수 있습니다.
/// 📝 ||
// 기본값을 넣어주고 싶을 때 사용할 수 있습니다.
// participantName이 0, undefined, 빈 문자열, null일 경우 'Guest'로 할당됩니다.
let participantName,
flag = 0;
const name = participantName || 'Guest';
/// 📝 &&
// flag가 true일 경우에만 실행됩니다.
flag && func();
// 객체 병합에도 이용할 수 있습니다.
const makeCompany = (showAddress) => {
return {
name: 'Cobalt. Inc.',
...(showAddress && { address: 'Seoul' }),
};
};
console.log(makeCompany(false)); // { name: 'Cobalt. Inc.' }
console.log(makeCompany(true)); // { name: 'Cobalt. Inc.', address: 'Seoul' }
객체에서 필요한 것만 꺼내 쓰는 것이 좋습니다.
const person = {
name: 'Lee Sun-Hyoup',
familyName: 'Lee',
givenName: 'Sun-Hyoup',
company: 'Cobalt. Inc.',
address: 'Seoul',
};
const { familyName, givenName } = person;
객체를 생성할 때 프로퍼티 키를 변수 이름으로 생략할 수 있습니다.
const name = 'Lee Sun-Hyoup';
const company = 'Cobalt';
const person = {
name,
company,
};
console.log(person); // { name: 'Lee Sun-Hyoup', company: 'Cobalt' }
함수에 객체를 넘길 경우 필요한 것만 꺼내 쓸 수 있습니다.
const makeCompany = ({ name, address, serviceName }) => {
return {
name,
address,
serviceName,
};
};
const cobalt = makeCompany({ name: 'Cobalt. Inc.', address: 'Seoul', serviceName: 'Present' });
ES6에 추가된 기능으로 객체의 키를 동적으로 생성 할 수 있습니다.
const nameKey = 'name';
const emailKey = 'email';
const person = {
[nameKey]: 'Lee Sun-Hyoup',
[emailKey]: 'kciter@naver.com',
};
console.log(person); // { name: 'Lee Sun-Hyoup', email: 'kciter@naver.com' }
!! 연산자를 이용하여 0, null, 빈 문자열, undefined, NaN을 false로 그 외에는 true로 변경할 수 있습니다.
function check(variable) {
if (!!variable) {
console.log(variable);
} else {
console.log('잘못된 값');
}
}
check(null); // 잘못된 값
check(3.14); // 3.14
check(undefined); // 잘못된 값
check(0); // 잘못된 값
check('Good'); // Good
check(''); // 잘못된 값
check(NaN); // 잘못된 값
check(5); // 5