풀이 1
constructor에서 flatted 배열 만들기
class NestedIterator {
constructor(nestedList){
this.flatted = [];
const flatten = (arr) => {
arr.forEach(item => item.isInteger()
? this.flatted.push(item.getInteger())
: flatten(item.getList()))
};
flatten(nestedList);
this.current = 0;
}
hasNext(){
return this.current < this.flatted.length;
}
next(){
const next = this.flatted[this.current];
this.current++;
return next;
}
}
풀이 2
- constructor에서 stack에 items를 쌓고
- hasNext
1) length가 0일 경우 false
2) top이 undefined일 경우 아래 item 확인
3) top이 integer일 경우 true
4) top이 list일 경우 list의 items를 stack에 쌓고 hasNext 재호출
- next에서
integer를 리턴
class NestedIterator {
constructor(nestedList){
this.stack = [];
for(let i=nestedList.length-1; i>=0; i--){
this.stack.push(nestedList[i]);
}
}
hasNext(){
if(this.stack.length===0){
return false;
}
const top = this.stack.pop();
if(top===undefined){
return this.hasNest();
}
if(top.isInteger()){
this.stack.push(top);
return true;
}else{
const list = top.getList();
for(let i=list.length-1; i>=0; i--){
this.stack.push(list[i]);
}
return this.hasNext();
}
}
next(){
return this.stack.pop().getInteger();
}
}
풀이 3
실행 컨텍스트
[[2,[2,3]],2,[2,3]];
function(){ // 0
const var0 = 2;
function(){
const var1 = 2;
const var2 = 3;
}
}
const var3 = 2; //1
function(){ //2
const var4 = 2;
const var5 = 3;
}
class Context {
constructor(list, outer) {
this.outer = outer;
this.lexicalEnvironment = list.map((node) =>
node.isInteger()
? new Identifier(node.getInteger(), this)
: new Context(node.getList(), this)
);
}
}
class Identifier {
constructor(value) {
this.variable = value;
}
}
class NestedIterator {
constructor(nestedList) {
this.global = new Context(nestedList, null);
this.currentLine = [0];
this.currentContext = this.global;
}
hasNext() {
const currentLine = this.currentLine[this.currentLine.length - 1];
if (currentLine === this.currentContext.lexicalEnvironment.length) {
this.currentLine.pop();
this.currentContext = this.currentContext.outer;
const nextLine = this.currentLine.pop() + 1;
this.currentLine.push(nextLine);
if (this.currentContext === null) {
// global을 모두 순회했을 경우 false
return false;
}
return this.hasNext();
}
const current = this.currentContext.lexicalEnvironment[currentLine];
if (current instanceof Context) {
this.currentContext = current;
this.currentLine.push(0);
return this.hasNext();
}
if (current instanceof Identifier) {
return true;
}
}
next() {
const currentLine = this.currentLine.pop();
const current = this.currentContext.lexicalEnvironment[currentLine];
this.currentLine.push(currentLine + 1);
return current.variable;
}
}