내가 보려고 만든 알고리즘 사전 ❤️🔥
MDN Object | MDN Array | MDN Set | MDN Map | MDN String
배열 선언 및 초기화 | declare array | init array | new Array | Array.from | []
const n = 20;
const arr = Array(n).fill(1); // 1로 채워진 길이 20의 배열 반환
// graph: 2차원 배열 생성
const graph = Array.from(Array(n), () => Array())
const graph = Array.from(Array(n), () => [])
const graph = Array.from({ length: n }, (_) => []);
const arr = Array.from(Array(m), () => Array(n)) // => m x n 배열
const arr = Array.from(Array(m), () => Array(n).fill(1)) // 1로 채워진 m x n 배열
// 1로 채워진 n개짜리 배열을 m개 선언 => m이 세로, n이 가로로 보임
// 0: (3) [1, 1, 1]
// 1: (3) [1, 1, 1]
// 2: (3) [1, 1, 1]
// 3: (3) [1, 1, 1]
const arr = new Array(n).fill(new Array(m).fill(0))
console.log(arr);
// 0: (4) [0, 0, 0, 0]
// 1: (4) [0, 0, 0, 0]
// 2: (4) [0, 0, 0, 0]
arr[2][2] = 1
console.log(arr);
// 0: (4) [0, 0, 1, 0]
// 1: (4) [0, 0, 1, 0]
// 2: (4) [0, 0, 1, 0]
위와 같이 선언하면 문제 없이 멀쩡해보이지만
arr[2][2] = 1
와 같이 한 요소만 바꾸어도 모든 배열이 수정된 것을 볼 수 있음
0
으로 구성된 길이m
의 배열을 한 개만 선언한 후에n
에 해당하는 모든 주소에 참조시키기 때문
따라서 바라보고있는 참조값은 모두 같음
Array.from(arrayLikeObject)
: 유사배열을 객체로 변환
set | new set | set to array | array to set
const arr = [1, 1, 2, 2, 2, 3];
const set = new Set(arr); // set 활용
const unique = [...set]; // 전개연산자 활용
console.log(arr); // [1, 1, 2, 2, 2, 3] *원본 유지
console.log(set); // {1, 2, 3}
console.log(unique); // [1, 2, 3]```
const arr = [1, 1, 2, 2, 2, 3];
const unique = arr.filter((item, index) => {
return arr.indexOf(item) === index;
});
console.log(arr); // [1, 1, 2, 2, 2, 3]
console.log(unique); // [1, 2, 3]
filter
를 통해arr
의 요소들을 돌면서item
으로 받음indexOf
를 통해arr
에서 처음 등장하는item
의index
를 찾음- 현재
item
의index
를 비교함- 같으면 중복되지 않은 요소이고, 다르다면 중복된 요소
- 중복되지 않은 요소들만
return
const arr = [1, 1, 2, 2, 2, 3];
let unique = [];
arr.forEach((item) => {
if (!unique.includes(item)) {
unique.push(item);
}
});
console.log(arr); // [1, 1, 2, 2, 2, 3]
console.log(unique); // [1, 2, 3]
forEach
를 통해arr
의 요소들을 돌면서item
으로 받음unique
배열에item
이 포함되어있지 않으면push
배열에서 자기 자신과 중복되는 요소를 찾아서 둘 다 제거하는 로직
ex) [1, 3, 3] => [1]
function deleteDup(arr) {
for (let i = 0; i < arr.length; i++) {
for (let j = 0; j < arr.length; j++) {
if (i !== j && arr[i] == arr[j]) {
arr.splice(i, 1)
arr.splice(j - 1, 1)
}
}
}
return arr
}
length가 3인 배열에서 다른 값 하나를 찾는 로직
ex) [1, 3, 1] => [3]
arrayX = arrayX.sort();
arrayy = arrayY.sort();
x = arrayX[1] === arrayX[0] ? arrayX[2] : arrayX[0];
y = arrayY[1] === arrayY[0] ? arrayY[2] : arrayY[0];
set | set.add(push) | set.has(includes) | set.size(length) | for (let item of set) {}
map | map.set(push) | map.has(includes) | map.size(length)
Set
객체는 값 콜렉션으로, 삽입 순서대로 요소를 순회할 수 있음.
하나의Set
내 값은 한 번만 나타날 수 있음
즉, 어떤 값은 그Set
콜렉션 내에서 유일함.
var mySet = new Set();
mySet.add(1); // Set { 1 }
mySet.add(5); // Set { 1, 5 }
mySet.add(5); // Set { 1, 5 }
mySet.add('some text'); // Set { 1, 5, 'some text' }
var o = {a: 1, b: 2};
mySet.add(o);
mySet.add({a: 1, b: 2}); // o와 다른 객체를 참조하므로 괜찮음!
mySet.has(1); // true
mySet.has(3); // false, 3은 set에 추가되지 않았음
mySet.has(5); // true
mySet.has(Math.sqrt(25)); // true
mySet.has('Some Text'.toLowerCase()); // true
mySet.has(o); // true
mySet.size; // 5
mySet.delete(5); // set에서 5를 제거함
mySet.has(5); // false, 5가 제거되었음
mySet.size; // 4, 방금 값을 하나 제거했음
console.log(mySet);// Set {1, "some text", Object {a: 1, b: 2}, Object {a: 1, b: 2}}
-
// 순서대로 항목을 (콘솔에) 기록: 1, "some text", {"a": 1, "b": 2}
for (let item of mySet) console.log(item);
// 순서대로 항목을 기록: 1, "some text", {"a": 1, "b": 2}
for (let item of mySet.keys()) console.log(item);
for (let item of mySet.values()) console.log(item);
// Set 객체를 배열 객체로 변환 (Array.from으로)
var myArr = Array.from(mySet); // [1, "some text", {"a": 1, "b": 2}]
// Set과 Array 사이 변환
mySet2 = new Set([1, 2, 3, 4]);
mySet2.size; // 4
[...mySet2]; // [1, 2, 3, 4]
Object
의 키는Strings
이며,Map
의 키는 모든 값을 가질 수 있다.
Object
는 크기를 수동으로 추적해야하지만,Map
은 크기를 쉽게 얻을 수 있다.
Map
은 삽입된 순서대로 반복된다.
const contacts = new Map()
contacts.set('Jessie', {phone: "213-555-1234", address: "123 N 1st Ave"})
contacts.has('Jessie') // true
contacts.get('Hilary') // undefined
contacts.set('Hilary', {phone: "617-555-4321", address: "321 S 2nd St"})
contacts.get('Jessie') // {phone: "213-555-1234", address: "123 N 1st Ave"}
contacts.delete('Raymond') // false
contacts.delete('Jessie') // true
console.log(contacts.size) // 1
배열 복사 | 객체 복사 | 클론 | clone | copy | shallow copy
깊은 복사 ► Copy 컴팩트 가이드 | 복사, 클론
const arr = [1, 1, 2, 2, 2, 3];
const copy = arr.slice()
console.log(arr); // [1, 1, 2, 2, 2, 3]
console.log(copy); // [1, 1, 2, 2, 2, 3]
console.log(arr == copy); // false => 참조값이 다름
const arr2 = [[1, 2], [3, 4], [5, 6]];
const copy2 = arr2.slice()
console.log(arr2); // [[1, 2], [3, 4], [5, 6]]
console.log(copy2); // [[1, 2], [3, 4], [5, 6]]
console.log(arr2 == copy2); // false => 참조값이 다름
1차원 배열은 깊은 복사가 가능한 것처럼 보이지만 2차원 이상의 배열은 깊은 복사가 불가능함(참조 값을 공유함)
const arr2 = [[1, 2], [3, 4], [5, 6]];
const copy2 = arr2.slice()
console.log(arr2); // [[1, 2], [3, 4], [5, 6]]
console.log(copy2); // [[1, 2], [3, 4], [5, 6]]
console.log(arr2 == copy2); // false
console.log(arr2[0] == copy2[0]); // true, 값이 같음
arr2[0].push(55)
console.log("1 arr2", arr2); // arr2[0]에만 넣었는데
console.log("1 copy2", copy2); // copy2[0] 에도 55가 들어감
arr2[0] = [7, 8] // 완전히 새로운 배열의 참조값을 할당했을 시
console.log("2 arr2", arr2); // [7, 8]
console.log("2 copy2", copy2); // [1, 2, 55]
console.log(arr2 == copy2); // false, 둘은 다른 값이 됨
const obj = { name: "maison", age: 18 }
const copy = Object.assign({}, obj)
console.log(obj); // { name: "maison", age: 18 }
console.log(copy); // { name: "maison", age: 18 }
console.log(obj == copy); // false => 참조값이 다름
Object.assign
을 통한 복사는 객체 내부의 객체를 깊이 복사해내지 못하고 참조값을 복사함
const obj2 = {
name: "maison", age: 18,
playlist: [
{ singer: "abc", title: "def" },
{ singer: "ghi", title: "jkl" }
]
}
const copy2 = Object.assign({}, obj2)
console.log(obj2); // 같은 값
console.log(copy2); // 같은 값
console.log(obj2 == copy2); // false, 참조값은 다름
console.log(obj2.playlist == copy2.playlist); // true, 참조 값이 같음 🚨
obj2.playlist[0].singer = "hell"
console.log(obj2); // ob2의 배열 내 객체를 수정하면
console.log(copy2); // copy2의 배열 내 객체도 함께 변경되어있음
const obj3 = {
name: "maison", age: 18,
playlist: { singer: "abc", title: "def" }
}
const copy3 = Object.assign({}, obj3)
console.log(obj3); // 같은 값
console.log(copy3); // 같은 값
console.log(obj3 == copy3); // false, 참조값은 다름
console.log(obj3.playlist == copy3.playlist); // true, 참조 값이 같음 🚨
obj3.playlist.singer = "hell"
console.log(obj3); // ob2의 객체 내 객체를 수정하면
console.log(copy3); // copy2의 객체 내 객체도 함께 변경되어있음
이거 보여주려고 어그로 끌었다
JSON.stringify
를 통해 JSON 문자열로 변환JSON.parse
를 통해 JSON 문자열을javascript
객체로 다시 변환
(JSON 문자열로 변환했다가 다시 객체로 변환하기에, 객체에 대한 참조가 없어짐)주의 🚨
1. 다른 방법에 비해서 성능적으로 느림
2.JSON.stringify
메소드가function
을undefined
로 처리함
const arr2 = [[1, 2], [3, 4], [5, 6]];
const copy2 = JSON.parse(JSON.stringify(arr2));
console.log(arr2); // [[1, 2], [3, 4], [5, 6]]
console.log(copy2); // [[1, 2], [3, 4], [5, 6]]
console.log(arr2 == copy2); // false
console.log(arr2[0] == copy2[0]); // true
arr2[0].push(55)
console.log(arr2, copy2); // 둘은 다른 값을 나타냄
참조값이 아닌 원시값을 비교하여 같은 배열 또는 객체인지 확인 가능
// 배열 비교 시, 순서가 상관없다면 비교 전 sort를 수행 JSON.stringify(arr1) === JSON.stringify(arr2) JSON.stringify(obj1) === JSON.stringify(obj2)
String | 문자 다루기 | slice | substring | split | splice
str.slice(beginIndex[, endIndex])
*endIndex를 포함하지 않고 추출함.
const str = 'The quick brown fox jumps over the lazy dog.';
console.log(str.slice(31)); // "the lazy dog."
console.log(str.slice(4, 19)); // "quick brown fox"
console.log(str.slice(-4)); // "dog."
console.log(str.slice(-9, -5)); // "lazy"
str.split([separator[, limit]])
*해당하는 문자열 기준으로 나누어 배열로 반환함
const str = 'The quick brown fox';
const words = str.split(' ');
console.log(words); // (4) ["The", "quick", "brown", "fox"]
const chars = str.split('');
console.log(chars[8]); // "k"
const strCopy = str.split();
console.log(strCopy); // ["The quick brown fox"]
Array
에 사용하는splice
함수는 잘라낸 배열과 자르고 남은 배열을 분리하여 활용할 수 있는 반면
String
의slice
함수는 원본을 수정하지 않기 때문에 자르고 남은 문자열을 알 수 없음
참고 : [stackoverflow] Is there a splice method for strings?
String.prototype.splice = function (index, count, add) {
var chars = this.split('');
chars.splice(index, count, add);
return chars.join('');
}
console.log(str.splice(10, 6)); // "The quick fox"
console.log(str.splice(4, 5, "slow")); // "The slow brown fox"
substr
: 사용 금지- slice VS substring 차이점
for
| forEach
(Array) | for ... of
(Array) | for ... in
(Object) *key값
JS 반복문 ► javascript 반복문 정리 | for | forEach | for in | for of
그래프 | DFS | BFS | 깊이우선탐색 | 너비우선탐색 | 완전 탐색
그래프 작성 시,
reduce()
+concat()
을 활용한 코드
이미 있으면 기존의 배열을, 없으면 새 빈 배열을 할당한 후, 합칠 배열을concat
const adjList = edges.reduce((G, [from, to]) => {
G[from] = (G[from] || []).concat(to);
G[to] = (G[to] || []).concat(from);
return G;
}, {});
arr
의 요소가Number
인 경우
function deleteDup(arr) {
const q = {}
arr.forEach(item => {
q[String(item)] = (q[String(item)] + 1 || 1);
})
for (let key in q) {
if (q[key] == 1) return key
}
}
(생략)
['Leo', 'Rui', 'fox', 'tiger'].reduce((a, c, i) => {
a[i] = c
return a
}, {}) // {0: "Leo", 1: "Rui", 2: "fox", 3: "tiger"}
concat return Array
join return String
const elements = ['Fire', 'Air', 'Water'];
console.log(elements.join()); // "Fire,Air,Water"
console.log(elements.join('')); // "FireAirWater"
console.log(elements.join('-')); // "Fire-Air-Water"
Number(str)
+str
String(num)
num + ''
자바스크립트로 알고리즘 정리하기 #9 다이나믹 프로그래밍 개념
프로그래머스 - 가장 큰 정사각형 찾기 (javascript)
const obj = {
a: 'hello',
b: {
c: 'hi',
d: {
e: 'wow'
}
}
}
// 기존
const a = obj.a
const b = obj.b
const c = obj.b.c
const d = obj.b.d
const e = obj.b.d.e
console.log(a, b, c, d, e)
// 구조 분해 할당
const { a, b: { c, d: { e }}} = obj
console.log(a, b, c, d, e) // b, d 는 not defined
// 구조 분해 할당 - 개선
const { a, b } = obj
const { c, d } = b
const { e } = d
console.log(a, b, c, d, e) // b, d 는 not defined
// 기존
const arr = [0, 1, 2, 3, 4]
const one = arr[0]
const two = arr[1]
const three = arr[2]
const four = arr[3]
const five = arr[4]
// 구조 분해 할당
const [one, two, three, four, five] = arr
// 구조 분해 할당(생략)
const [one, , three, , five] = arr
$el.addEventListener('click', () => {
console.log(event.target) // target
})
callback
함수에event
는 브라우저에서 자동으로 삽입해줌
function callback() {
console.log(event.target) // target
}
$el.addEventListener('click', callback)
callback 함수를 따로 분리한 후,
addEventListener의 callback 함수 자리에 함수를 삽입
함수 자리에 함수가 들어간 적절한 상황임
function callback(event, num) {
console.log('e', event.target) // undefined
console.log('n', num) // undefined
}
$el.addEventListener('click', callback(0))
callback(0)
를 입력하는 동시에 함수가 실행되고,
callback 함수의 return 값이 명시되어있지 않기 때문에
암시적으로return undefined
가 설정됨.
즉, 함수 자리에 return 값(undefined)이 들어가는 상황으로
$el.addEventListener('click', undefined)
와 같아짐
따라서 인수를 전달하고자 할 때에는 아래와 같이 고차원 함수를 활용
function callback(num) {
return () => {
console.log('e', event.target) // target
console.log('n', num) // 0
}
}
$el.addEventListener('click', callback(0))
$el.addEventListener('click', { console.log... })
와 같아짐
즉, 함수 자리에 callback 함수의 return 값을 넣는데,
그 return 값이 바로 함수.
따라서 함수 자리에 함수를 넣은 적절한 상황임
function callback(num) {
console.log('e', event.target) // target
console.log('n', num) // 0
}
$el.addEventListener('click', () => {
callback(0)
})
const arr = [
["td", "td", "td"],
["td", "td", "td"],
["td", "td", "td"],
]
const flatedArry = arr.flat()
console.log(flatedArry); // ["td", "td", "td", "td", "td", "td", "td", "td", "td"]
const arr1 = [true, true, true, false]
console.log(arr1.every(el => el)) // false
const arr2 = [true, true, true, true]
console.log(arr2.every(el => el)) // true
const arr1 = [true, true, true, false]
console.log(arr1.some(el => el === false)) // false
const arr2 = [true, true, true, true]
console.log(arr2.some(el => el === false)) // true```
<form class="wrapper">
<input id="name-input">
<input id="age-input">
</form>
const wrapper = document.querySelector('.wrapper')
wrapper.addEventListener('click', () => {
const name = event.target['name-input']
console.log(name)
})
(수정 중)
function myFunc() {
}
myFunc = () => {
}
const box = 0
console.log(box || 'here') // here
const box = 0
console.log(box || 'here') // here
console.log(box ?? 'here') // 0
const obj = {
name: {
first: 'protect',
family: 'me'
},
age: '18'
}
console.log(obj.name.first[0]) // p
// console.log(obj.second.first[0]) // 에러: 'first' of undefined
console.log(obj.second?.first[0]) // undefined
append
는 할 때마다 다시 그려지므로 여러 개를 연속으로 하면 매우 비효율적DocumentFragment
는 다른 노드를 담는 임시 컨테이너 역할을 하는 특수 목적의 노드const $fragment = document.createDocumentFragment()
const exp = '100-200*300-500+20'
const spread = exp.split(/-|\+|\*/)
console.log(spread) // (5) ['100', '200', '300', '500', '20']
[Javascript] 배열 중복 제거하는 3가지 방법
자바스크립트 객체 복사하기
[stackoverflow] Is there a splice method for strings?
Photo by Marc-Olivier Jodoin on Unsplash