첫 번째 HA가 아침 9시에 시작해서 하루를 꼬박 넘겨 밤 12시 30분 무렵에서야 마무리되었다.
누가 채찍으로 등을 찰싹찰싹 때리지 않으면 도무지 진득하게 집중하지 못하는 정신머리 반, 다 풀어봤던거 약간씩 난이도 올려서 낸건데도 처음이랑 똑같이 헤매는 모지리 두뇌 반으로 어기적 어기적 헤쳐나가다보니 이렇게 오래걸렸다. 세상에...
이머시브 들어와서 배운것들 이번주에 단디 붙들어매지 않으면 이 뒤가 굉장히 고달플 것 같다는 생각이 강하게 들어서 이번에 좀 빡세게 복기하면서 한 줄 한 줄 음미해보려고 한다. ㄱㄱ!
company.name
만 Unemployed
에서 google
로 바뀌어야 합니다.const obj = {
name: 'Lee',
company: {
name: 'Unemployed', // <- 요거. 요걸 google 로 바꿔야 한다.
skill: ['Development', 'Writing'],
role: {
name: 'Software Engineer'
}
},
age: 35
}
const gettingJob = () => {
return { 코드 짜넣는 곳 }
{...obj}
하면 obj 객체의 내용이 똑같이 전개된다는 건 알고 있었다. 문제는 어떻게 obj의 일부 내용을 바꾸면서 전개시킬 수 있는지를 알 수 없었다. 구글링 시작.
const obj = { name: "ggami", specis: "puppy" };
const change = { ... obj, specis: "dog" };
console.log(change) // { name: "ggami", specis: "dog" }
일단 obj를 전개시켜놓고 콤마를 찍은 뒤, 그 뒤에 전개된 내용 중 변경하고 싶은 내용을 적으면 된다는 사실을 알게 되었다. 전개시켜놓고, 변경한다. 반대순서는 안된다. 이제 이걸 응용쳐서 본 문제를 풀면 되겠다 싶었다.
const gettingJob = () => {
return { ...obj, company: { ...obj.company, name: 'google' } }
}
먼저 { ...obj }
로 obj의 내용을 전개시켜놓고, { ...obj, company: { } }
요런 식으로 obj의 내용 중 company 프로퍼티의 내용을 변경할 것임을 알린다. 그럼 company의 value 인 객체 내부에 있는 name프로퍼티를 어떻게 변경할 수 있을까? company 객체의 내부로 한 걸음 들어가서 살펴보면, 아래와 같이 할 수 있다.
위에서 ggami 의 specis를 puppy에서 dog 로 바꾼 것과 같은 원리로, { ...obj.company, name: "google" }
이렇게 하면 company 객체의 name 값을 바꿀 수 있다. 이제 한 걸음 뒤로 빠져서 바라보면 전체 코드는 위에 작성해놓은 결과물과 같은 모습이 되어있을 것이다.
const Queue = function () {
this._storage = {}
};
Queue.prototype.add = function () {};
Queue.prototype.remove = function() {};
add까지는 알겠는데 remove 메소드를 O(1)의 시간 복잡도로 구현하는 방법을 모르겠다. O(1) 이 되려면 탐색과정 없이 객체 맨 앞에 있는 프로퍼티를 탁 잡아 없애야 하는데, 배열에서야 인덱스가 있으니까 쉽지만 객체에서 어찌해야 할꼬? 또 고민과 구글링 시작.
객체의 맨 앞 프로퍼티를 자동으로 탐지해서 삭제해주는 메소드는 존재하지 않는 것 같다. 그럼 어떡해?
객체를 배열화 해야한다는 결론을 냈다. 즉, 수동으로 인덱스를 만들어야 한다.
item 을 queue에 추가하려고 한다면, { index: item }
형식으로 인덱스를 키로 가진채로 저장되게끔 해야 한다. 그래야 나중에 remove 하려고 할 때 맨 앞놈이 누군지 탐색하지 않아도 잡아낼 수 있다.
그럼 이제 remove 메소드를 사용하면 delete this._storage(0) 를 하면 된다고 넘어가고, 그 다음 작업이 고민이다. 맨 앞 프로퍼티가 삭제된다고 해도 그 뒤에 있던 프로퍼티들이 키값으로 담긴 index는 바뀌지 않기 때문이다. 문제 해결을 위한 힌트는 어느정도 얻었으니 나머지는 코드를 짜면서 고민해보기로 한다.
const Queue = function () {
this._storage = {}
this.firstIndex = 0
this.length = 0
};
Queue 생성자에 firstIndex 프로퍼티를 추가해서 this._storage[this.firstIndex]
하면 곧바로 맨 앞 프로퍼티를 가리킬 수 있도록 했다. fitstIndex 를 1씩 증가시키면 remove 메소드가 호출될 때마다 맨 앞 프로퍼티가 지목될 수 있다.
Queue.prototype.add = function (item) {
this._storage[this.length + this.firstIndex] = item
this.length++
};
최초에 this.length + this.firstIndex
는 0이고, 그 다음은 1, 그 다음은 2 이런 식으로 인덱스 역할을 하는 key가 만들어지고, 그 value 로 item 이 저장된다. 그리고 firstIndex 는 0으로 고정되어 있지. 왜 굳이 length 에 firstIndex 를 더해줬는지는 아래 remove 메소드를 보면서 이야기한다.
Queue.prototype.remove = function() {
// storage 가 비었으면 삭제할게 없으므로 undefined 반환
if (this.length <= 0) {
return undefined
}
// 맨 앞 프로퍼티 제거
let removeItem = this._storage[this.firstIndex]
delete this._storage[this.firstIndex]
// 첫 번째 인덱스, 객체의 길이 재조정
this.firstIndex++
this.length--
return removeItem;
};
맨 앞 프로퍼티가 삭제되었으므로 this.length
는 1 줄어야 하고, 이제 맨 앞 프로퍼티의 key 는 0 이 아닌 1 이므로 this.firstIndex
는 1 증가해야 한다. 그러면 this.length + this.firstIndex
값은 변한게 없으므로 add
메소드에서 인덱스 역할을 하는 key도 여전히 제대로 동작한다. 깔끔!