面试题之-扁平化数组

面试中经常会遇到一道扁平化数组的题目:写一个函数,将输入数组 [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()方法的使用

// 借用数组的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]);

…扩展运算符

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

这篇文章目前没有评论。

回复

(必填项)

(必填项)

(可选)