面試題之-扁平化數組

面試中常常會遇到一道扁平化數組的題目:寫一個函數,將輸入數組 [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類型this

// 借用數組的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函數的使用,以及返回值做爲一個遍歷器對象的使用,以及數組...(擴展運算符)的使用。prototype

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的使用code

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函數+遞歸實現htm

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);

參考:面試題之-扁平化數組遞歸

相關文章
相關標籤/搜索