资讯专栏INFORMATION COLUMN

JavaScript 数组展开(扁平化)和underscore的 flatten

awokezhou / 1746人阅读

摘要:原文地址数组展开就是将嵌套的数组扁平化转换为一维的判断每一项是否是数组,然后递归递归调用数组在调用会将数组转换成再执行方法会变成还需要将所有的参数转换为数字,所以这种方式的不足就是如果数组里面是既有数字又有字符串,会全部展开为数字转为数字方

原文地址
数组展开就是将嵌套的数组扁平化(转换为一维的)eg:

const arr=[[[1, 2], [1, 2, 3]], [1, 2]] => [1, 2, 1, 2, 3, 1, 2] 
console.log(flatten(arr))  //[1,2,1,2,3,1,2]
1、判断每一项是否是数组,然后递归
const arr=[[[1, 2], [1, 2, 3,"a"]], [1, 2,"a"]]
function flatten(arr){
    let result=[]
    for(let i=0,l=arr.length;i
2、toString

数组在调用toString()会将数组转换成"1,2,1,2,3,1,2",再执行split(",")方法会变成["1", "2", "1", "2", "3", "1", "2"]
还需要将所有的参数转换为数字,所以这种方式的不足就是如果数组里面是[1,2,3,"4","5"]既有数字又有字符串,会全部展开为数字

const arr=[[[1, 2], [1, 2, 3]], [1, 2]]
function flatten(arr){
    return arr.toString().split(",").map(item => {
        //转为数字
        return +item
    })
}
console.log(flatten(arr),arr)
3、reduce方法
const arr=[[[1, 2], [1, 2, 3,"a"]], [1, 2,"b"]]
function flatten(arr){
    return arr.reduce((pre,next) => {
        return pre.concat(Array.isArray(next) ? flatten(next) : next)  //如果是数组同样的递归调用
    },[])
}
console.log(flatten(arr),arr)
4、解构的方式

利用es6新增结构方法可以提取一层的方法,来一层层提取出来

const arr=[[[1, 2], [1, 2, 3,"a"]], [1, 2,"b"]]
function flatten(arr){
    while(arr.some(item => Array.isArray(item))){
        //如果当前数组中还有数组,则展开
        arr=[].concat(...arr)
    }
    return arr
}
console.log(flatten(arr),arr)
5、js原生方法flat

flat(depth) 方法会按照一个可指定的深度递归遍历数组,并将所有元素与遍历到的子数组中的元素合并为一个新数组返回。参数depth表示要提取嵌套数组的结构深度,默认为1

const arr=[[[1, 2], [1, 2, 3,"a"]], [1, 2,"b"]]
arr.flat(Infinity)
6、Underscore.js的flatten方法

先上代码

/**
 * param {Array} input 要操作的数组
 * param {Boolean} shallow 浅展开,及为true时,只展开一层,为false是深度展开
 * param {Boolean} strict 遍历第一层时,是否放弃非数组对象
 * param {Array} output 保存最后输出的内容
 */
var flatten = function(input, shallow, strict, output = []) {
  var idx = output.length;
  for (var i = 0, length = getLength(input); i < length; i++) {
    var value = input[i];
    // 说明flatten方法对类数组对象也有支持
    if (isArrayLike(value) && (_.isArray(value) || _.isArguments(value))) {
      if (shallow) {
        // 只展开一层
        var j = 0, len = value.length;
        while (j < len) output[idx++] = value[j++];
      } else {
        // 深度迭代,递归展开
        flatten(value, shallow, strict, output);
        idx = output.length;
      }
    } else if (!strict) {
      output[idx++] = value;
    }
  }
  return output;
};

output将返回数组当作参数传递,可以省去在递归的时候将数据一层层的return到上一层,在性能上会有所提升
::: tip 注意
shallowfalse时,stricttrue是,返回的永远时[] ,这是因为,当shallowfalse时是深度迭代,,当最后迭代到不是数组的时候,就会进入到else if中,如果此时stricttrue则就不会进入到这个分支中,那么output就永远不会被操作,
:::

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/104278.html

相关文章

  • JavaScript专题之数组平化

    摘要:专题系列第九篇,讲解如何实现数组的扁平化,并解析的源码扁平化数组的扁平化,就是将一个嵌套多层的数组嵌套可以是任何层数转换为只有一层的数组。 JavaScript 专题系列第九篇,讲解如何实现数组的扁平化,并解析 underscore 的 _.flatten 源码 扁平化 数组的扁平化,就是将一个嵌套多层的数组 array (嵌套可以是任何层数)转换为只有一层的数组。 举个例子,假设有个...

    tuantuan 评论0 收藏0
  • JavaScript 数组展开以及 underscore 重要内部方法 flatten 详解

    摘要:今天要讲的是数组展开以及和数组展开息息相关的一个重要的内部方法。也是个布尔值,当为并且也为时,能过滤参数元素中的非数组元素。首先并不需要对数组深度展开,其次传入的是数组,对于非数组元素可以直接忽略。 Why underscore (觉得这一段眼熟的童鞋可以直接跳到正文了...) 最近开始看 underscore.js 源码,并将 underscore.js 源码解读 放在了我的 201...

    binaryTree 评论0 收藏0
  • JavaScript专题系列文章

    摘要:专题系列共计篇,主要研究日常开发中一些功能点的实现,比如防抖节流去重类型判断拷贝最值扁平柯里递归乱序排序等,特点是研究专题之函数组合专题系列第十六篇,讲解函数组合,并且使用柯里化和函数组合实现模式需求我们需要写一个函数,输入,返回。 JavaScript 专题之从零实现 jQuery 的 extend JavaScritp 专题系列第七篇,讲解如何从零实现一个 jQuery 的 ext...

    Maxiye 评论0 收藏0
  • 1625行,解开 underscore.js 面纱 - 第五章

    摘要:对多个一维数组进行并运算,实际上就是加强版的。所以我要说的是这个函数,将传入参数转换为一个数组进行到的回调函数中,以此达到函数接到的是一个一维数组的集合。 每次小章节的开题都烦恼写什么好,所以直接接下文 (~o▔▽▔)~o o~(▔▽▔o~) 。 _.first = _.head = _.take = function(array, n, guard) { if (arra...

    Rango 评论0 收藏0
  • JavaScript专题系列20篇正式完结!

    摘要:写在前面专题系列是我写的第二个系列,第一个系列是深入系列。专题系列自月日发布第一篇文章,到月日发布最后一篇,感谢各位朋友的收藏点赞,鼓励指正。 写在前面 JavaScript 专题系列是我写的第二个系列,第一个系列是 JavaScript 深入系列。 JavaScript 专题系列共计 20 篇,主要研究日常开发中一些功能点的实现,比如防抖、节流、去重、类型判断、拷贝、最值、扁平、柯里...

    sixleaves 评论0 收藏0

发表评论

0条评论

awokezhou

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<