면접문제 - 편평화 수조

면접에서 편평한 수조의 제목을 자주 볼 수 있다. 함수를 써서 입력수조[1, [2, [3, [4]], 5]][1, 2, 3, 4, 5]의 형식으로 바꾸는 것이다.
처음에 나는 이 문제를 통해 귀속적인 사용을 고찰한 줄 알았는데 나중에 자세히 생각해 보니 일이 이렇게 간단한 것이 아니었다. 본고는 몇 가지 방식의 실현을 통해 이 문제가 고찰해야 할 내용을 이해하고자 한다.

귀속


귀환은 첫 번째 사고방식이다. 보통 사람들은 이 방법을 생각하지만 이 문제가 귀환을 고찰하는 것일 뿐이라면 이렇게 문제를 내지 않을 것이다.
function flatten (arr) {
  var result = [];
  (function(arr) {
    var self = arguments.callee;
    arr.forEach(function(item) {
      // Array.isArray(item)
      if(item instanceof Array) {
        self(item);
      } else {
        result.push(item);
      }
    });
  })(arr);
  return result;
}

암시적 유형 변환


주요 고찰 수조toString(), valueOf() 방법의 사용, 이런 상황은 수조 요소 유형이 String과 Number이고 다른 상황은 모두 String 유형으로 전환된다.
//  toString 
function flatten (arr) {
  var str = arr.toString();
  return str.split(',');
}

//  valueOf 
Array.prototype.valueOf = function() {
  return this.join(',')
};
function flatten2 (arr) {
  var str = arr.valueOf();
  return str.split(',');
}

Generator


ES6에서 Generator 함수의 사용과 리턴 값이 범람기 대상으로서의 사용, 그리고 그룹을 고찰...(확장 연산자) 사용
function *_flatten (arr) {
  for(let i = 0; i < arr.length; i++) {
    const item = arr[i];
    if(Array.isArray(item)) {
      yield *_flatten(item);
    } else {
      yield item;
    }
  }
}
const flatten = arr => [..._flatten(arr)];

Symbol.iterator


ES6에서 Symbol을 고찰하다.iterator 사용
Array.prototype[Symbol.iterator] = function () {
  let arr = [].concat(this);
  let first = function (arr) {
    return arr.shift();
  };

  return {
    next: function() {
      let item = first(arr);
      if (item) {
        return {
          value: item.toString(),
          done: false
        }
      } else {
        return {
          done: true
        }
      }
    }
  };
}

const flatten = arr => {
  let res = [];
  for(let i of arr) {
    res.push(i);
  }
  return res.join(',').split(',');
};

또는generator 함수 + 귀속을 통해 실현
Array.prototype[Symbol.iterator] = function* (array) {
 let arr = array || this;
 let sel = arguments.callee;
 
  for(let i = 0; i < arr.length; i++) {
    const item = arr[i];
    if(Array.isArray(item)) {
      yield *sel(item);
    } else {
      yield item;
    }
  }
}
// test
var arr = [1, [2, [3, [4]], '5']];
console.log([...arr]);

...확장 연산자 + Array.prototype.some

function flatten(arr) {
  var arr;
  while (arr.some(v => Array.isArray(v))) {
    arr = [].concat(...arr);
  }
  return arr;
}

Array.prototype.flat()

flat()는 ES6에 새로 추가된 수조 방법으로 이 방법은 새로운 수조로 되돌아와 원 데이터에 영향을 주지 않는다.
[1, [2, [3, [4]], 5]].flat(Infinity);

참고: 면접문제 - 편평화 수조

좋은 웹페이지 즐겨찾기