TIL 006
✏️ 25.01.02 To do list
- 코드카타 문제 1~5
- Javascript 기본 문법 1주차 복습
- Javascript 기본 문법 2주차
- Javascript 기본 문법 2주차 과제
- Javascript 기본 문법 3주차 3-5까지
- 좋은 개발자 특강
오늘 배운 것들
- ES6 문법
- 일급객체로서의 함수
- Map 사용 방법
- Set 사용 방법
오늘 학습한 내용
01 ES6 문법
ECMAScript 6(ES6)는 Javascript 버전 중 하나로 2015년에 발표되었음
새로운 문법과 기능을 도입하여 Javascript 개발자들이 보다 쉽고 효율적으로 코드를 작성할 수 있도록 개선함
ES6가 항상 언급되는 이유
why? 2015년도에 대규모 문법적 향상 및 변경이 있었기 때문에
새로 나온 문법
(1) let, const
(2) 화살표 함수 (Arrow function)
(3) 삼항 연산자 (Ternary Operator)
(4) 구조분해할당 (Destructuring)
배열이나 객체의 속성을 분해해서 변수에 담을 수 있게 함
📌 배열
let arr = ["value1", "value2", "value3"];
let [a, b, c, d = 4] = arr;
console.log(a); // 결과: value1
console.log(b); // 결과: value2
console.log(c); // 결과: value3
console.log(d); // d의 값이 할당되지 않은 경우 undefined를 출력함
📌 객체
let user = {
name: "Bob",
age: 30,
};
let { name, age, birthday = "today" } = user;
console.log(name);
console.log(age);
console.log(birthday); // birthday의 값이 할당되지 않은 경우 undefined를 출력함
// 새로운 이름으로 할당
let { name: newName, age: newAge } = user;
console.log(newName);
console.log(newAge);
(5) 단축 속성명 (Property shorthand)
key와 value의 이름이 동일할 경우 생략이 가능함
const name = "Bob";
const age = 30;
// key-value pair
// name: name, age: age처럼 key와 value의 이름이 동일할 경우 생략 가능함
const obj = { name, age };
(6) 전개 구문 (Spread operator)
배열과 객체를 묶었던 괄호가 사라지고 안에 있는 요소들이 순서대로 전개됨
새로운 배열이나 객체를 만들 때 용이함
📌 배열
let arr = [1, 2, 3];
let newArr = [...arr, 4]; // 대괄호가 사라지고 안에 있는 요소가 전개됨
console.log(newArr);
📌 객체
let user = {
name: "Bob",
age: 30,
};
let user2 = { ...user };
console.log(user2);
(7) 나머지 매개변수 (Rest parameter)
매개변수의 개수가 명확하지 않을 때 사용
function exampleFunc(a, b, c, ...args) {
console.log(a, b, c); // 결과: 1, 2, 3
console.log(...args); // 결과: 4, 5, 6
}
exampleFunc(1, 2, 3, 4, 5, 6);
(8) 템플릿 리터럴 (Templete literal)
`` : 백틱
여러 줄로 이루어진 문자열과 문자 보간기능을 사용하게 만들어 주는 문자열 리터럴 표현식
백틱 안에서 좀 더 자유롭게 표현이 가능함
const textValue = "안녕하세요";
console.log(`Hello wolrd! ${textValue}`);
console.log(`
Hello
My name is Bob!!
Nice to meet you!!
`); // 멀티라인이 가능하여 표현할 수 있는 범위가 넓어짐
02 일급 객체로서의 함수
함수 = 일급 객체 (First-Class Object)
= 다른 객체들에 일반적으로 적용 가능한 연산을 모두 지원하는 객체
So, 함수를 매우 유연하게 사용할 수 있음
(1) 변수에 함수를 할당할 수 있다
함수가 값으로 취급되기 때문에 변수에 할당할 수 있음
변수를 통해 나중에 함수를 재사용할 수 있음
const sayHello = function () {
console.log("Hello!");
};
(2) 함수를 인자로 다른 함수에 전달할 수 있다
함수가 값으로 취급되기 때문에 다른 함수의 인자로 전달할 수 있음
콜백 함수 또는 고차 함수를 작성하는데 사용됨
콜백 함수: 매개변수로 함수를 받음
고차 함수: 함수를 인자로 받거나 return함
const sayHello = function () {
console.log("Hello!");
};
function callFunction(func) {
// 매개변수로 받은 변수가 사실 함수다
func();
}
callFunction(sayHello); // 결과: Hello!
(3) 함수를 반환할 수 있다
function createAdder(num) {
return function (x) {
return x + num;
};
}
const addFive = createAdder(5); // addFive가 함수가 되어 매개변수를 전달할 수 있음
console.log(addFive(10)); // 결과: 15
(4) 객체의 속성으로 함수를 할당할 수 있다
const person = {
name: "John",
age: 31,
isMarried: true,
sayHello: () => {
console.log(`Hello, My name is ${this.name}`); // 화살표 함수는 this를 바인딩하지 않음
},
// sayHello: function () {
// console.log(`Hello, My name is ${this.name}`); // this는 자기자신의 객체를 가리킴
// },
};
person.sayHello(); // 결과: Hello, My name is undefined
(5) 배열의 요소로 함수를 할당한다
const myArr = [
function (a, b) {
return a + b;
},
function (a, b) {
return a - b;
},
];
console.log(myArr[0](1, 2));
console.log(myArr[1](1, 2));
03 Map과 Set
Map과 Set이 등장한 이유
Javascript에서 객체와 배열을 이용해서 다양하고 복잡한 프로그램을 만들 수 있음
그럼에도 불구하고 현실세계의 여러가지 문제를 해결하기에는 부족함
So, 이러한 한계를 극복하고자 새로운 자료구조인 Map과 Set이 등장함
기존의 객체, 배열보다 데이터의 구성, 검색, 사용을 효율적으로 처리함
Map
key-value를 저장하는 객체와 비슷함
📌 특징
객체와 달리 key에 어떤 데이터 타입도 다 들어올 수 있음
키가 정렬된 순서대로 저장되기 때문에 추가한 순서대로 반복할 필요가 없음
📌 기능
key-value 검색, 삭제, 제거, 여부 확인
📌 new Map() : Map 만들기
const myMap = new Map();
📌 map이름.set(key,value) : key와 value를 저장함
myMap.set("one", 1);
myMap.set("two", 2);
myMap.set("three", 3);
📌 map이름.get(key) : key에 해당하는 값을 반환함, key가 존재하지 않으면 undefined를 반환함
myMap.get("one"); // 결과: 1
📌 map이름.has(key) : 해당 key가 존재하면 true, 없으면 false를 반환함
console.log(myMap.has("two")); // 결과: true
📌 map이름.delete(key) : key에 해당하는 값을 삭제함
myMap.delete("three")
📌 map이름.clear() : Map 안의 모든 요소를 제거함
myMap.clear()
📌 map이름.size : 요소의 개수를 반환함
console.log(myMap.size); // 결과: 3
Map의 반복 - keys(), values(), entries()
반환하는 값 = iterator
= 요소 하나하나를 반복할 수 있도록 배열 or 객체와 비슷한 형태로 열거되어있는 자료구조
📌 for ~ of 반복문
const myMap = new Map();
myMap.set("one", 1);
myMap.set("two", 2);
myMap.set("three", 3);
for (const key of myMap.keys()) {
console.log(key); // 결과: one two three
}
for (const value of myMap.values()) {
console.log(value); // 결과: 1 2 3
}
for (const entry of myMap.entries()) {
console.log(entry); // 결과: [ 'one', 1 ] [ 'two', 2 ] [ 'three', 3 ]
}
Set
고유한 값을 저장하는 자료구조
📌 특징
값만 저장하며 key는 저장하지 않음
값이 중복되지 않는 유일한 요소로만 구성됨
📌 기능
값 추가, 검색, 값 삭제, 모든 값 제거, 존재 여부 확인
📌 new Set() : Set 생성
const mySet = new Set()
📌 set이름.add(value) : Set에 새로운 값 추가
mySet.add("value1");
mySet.add("value2");
mySet.add("value3");
mySet.add("value4");
mySet.add("value5");
📌 set이름.has(value) : Set에 들어있는 값 검색하기
console.log(mySet.has("value1"));
📌 set이름.size : 요소의 개수를 반환함
console.log(mySet.size);
Set의 반복 - values()
📌 for ~ of 반복문
for (const value of mySet.values()) {
console.log(value);
}
문제 - 해결 과정
01 문자열 내 마음대로 정렬하기
문제
문자열로 구성된 리스트 strings와, 정수 n이 주어졌을 때, 각 문자열의 인덱스 n번째 글자를 기준으로 오름차순 정렬하려 합니다. 예를 들어 strings가 ["sun", "bed", "car"]이고 n이 1이면 각 단어의 인덱스 1의 문자 "u", "e", "a"로 strings를 정렬합니다.
[제한 조건]
strings는 길이 1 이상, 50이하인 배열입니다.
strings의 원소는 소문자 알파벳으로 이루어져 있습니다.
strings의 원소는 길이 1 이상, 100이하인 문자열입니다.
모든 strings의 원소의 길이는 n보다 큽니다.
인덱스 1의 문자가 같은 문자열이 여럿 일 경우, 사전순으로 앞선 문자열이 앞쪽에 위치합니다.
내가 생각한 로직
순서
- for문을 이용하여 배열 안에 있는 각각의 요소에 접근한다
- n번째에 해당하는 알파벳에 접근한다
- 해당 알파벳끼리 비교하여 더 큰 값이 작은 값보다 앞에 위치하게 한다
- 위의 과정을 반복하여 오름차순으로 단어를 정리한다
필요한 지식
- 알파벳을 오름차순으로 정리하는 방법
- sort() 함수
- ‘a’는 ‘z’보다 작다 ⇒ ‘a’ < ‘z’ = true
📍 첫번째 문제 상황 : n번째 알파벳을 구하는 것은 가능했지만, 이들끼리 크기를 비교하고, 배열들끼리 순서를 바꾸는 코드를 구현하는 것이 어려웠음
결국, 문제풀이 팁을 보면서 코드를 구현하였음
- n번째 문자에 접근하는 것까지는 잘 구현하였음
- n번째 문자를 해당 문자열 맨앞에 붙이면 sort()를 사용할 수 있다는 것을 알게 되었음
- 이후 맨 앞에 붙은 문자를 지우면 되는 것이었음
해결 방법
function solution(strings, n) {
let strings1 = [];
let strings2 = [];
for (let i = 0; i < strings.length; i++) {
let result = strings[i][n] + strings[i];
strings1.push(result);
}
strings1.sort();
for (let i = 0; i < strings1.length; i++) {
let result = strings1[i].substr(1, strings1[i].length);
strings2.push(result);
}
return strings2;
}
다른 해결 방법
🌟 위의 코드에서 좀 더 간결해진 코드
function solution(strings, n) {
var answer = [];
// 1. 문자열 가장 앞 글자를 붙인 배열 만들기
for (let i = 0; i < strings.length; i++) {
strings[i] = strings[i][n] + strings[i];
}
// 2. 해당 배열을 사전순으로 정렬(sort)
strings.sort();
// 3. 앞글자 제거 후 리턴
for (let j = 0; j < strings.length; j++) {
strings[j] = strings[j].replace(strings[j][0], "");
}
return answer;
}
function solution(strings, n) {
return strings.sort((s1, s2) => s1[n] === s2[n] ? s1.localeCompare(s2) : s1[n].localeCompare(s2[n]));
}
느낀 점
코드를 구현할 때 1/3까지는 어떻게 구현했어도 나머지 2/3를 구현하지 못해 해결 방법을 보게 되는 일이 생겨 조금 허탈하다. 어떻게 해야 깔끔하고 가독성이 좋은 코드를 구현할 수 있을까 계속 고민하게 된다. 해설 방법을 보지 않고도 코드를 구현할 수 있는 능력을 얼른 갖고 싶다.