es6删除数组某一项_精学手撕系列——数组扁平化

参考文章:面试官连环追问:数组拍平(扁平化) flat 方法实现

编者荐语:

在前端面试中,手写flat是非常基础的面试题,通常出现在笔试或者第一轮面试中,主要考察面试者基本的手写代码能力和JavaScript的基本功。

今天就带大家从0了解flat特性到手写实现flat,再到接住面试官的连环追问中重新学习一遍数组扁平化flat方法

Array.prototype.flat()

一段代码总结Array.prototype.flat()特性

注:数组拍平方法 Array.prototype.flat() 也叫数组扁平化、数组拉平、数组降维。

let arr = [12, 23, [34, 56, [78, 90, 100, [110, 120, 130]]]];

console.log(arr.flat()); 
// [ 12, 23, 34, 56, [ 78, 90, 100, [ 110, 120, 130 ] ] ]

console.log(arr.flat(2));
// [ 12, 23, 34, 56, 78, 90, 100, [ 110, 120, 130 ] ]

console.log(arr.flat(Infinity));
// [12, 23, 34, 56, 78, 90, 100, 110, 120, 130]

console.log(arr.flat(0));
// [12, 23, [34, 56, [78, 90, 100, [110, 120, 130]]]];

console.log(arr.flat(-10));
// [12, 23, [34, 56, [78, 90, 100, [110, 120, 130]]]];

let arr2 = [12, 23, [34, 56, ,]]
console.log(arr.flat());
// [ 12, 23, 34, 56 ]

Array.prototype.flat() 特性总结

  • Array.prototype.flat() 用于将嵌套的数组“拉平”,变成一维的数组。该方法返回一个新数组,对原数据没有影响。

  • 不传参数时,默认“拉平”一层,可以传入一个整数,表示想要“拉平”的层数。

  • 传入 <=0 的整数将返回原数组,不“拉平”

  • Infinity 关键字作为参数时,无论多少层嵌套,都会转为一维数组

  • 如果原数组有空位,Array.prototype.flat() 会跳过空位。

面试官 N 连问:

第一问:下面数组如何实现扁平化?

let arr = [
  [1, 2, 2],
  [3, 4, 5, 5],
  [6, 7, 8, 9, [11, 12, [12, 13, [14]]]], 10
];

小伙伴首先想到的肯定是用 ES6 的Array.prototype.flat方法呀

方法一:flat

arr = arr.flat(2);
// [ 1, 2, 2, 3, 4, 5, 5, 6, 7, 8, 9, 11, 12, [ 12, 13, [ 14 ] ], 10 ]

flat中传入数字时,是扁平对应的层数,显然这不是我们想要的,因为它还没有完全展开。

这是,flat函数中就为我们提供了一个参数Infinity,译为无穷的意思。

arr = arr.flat(Infinity);
/* [
   1,  2,  2, 3,  4,  5,  5,
   6,  7,  8, 9, 11, 12, 12,
  13, 14, 10
] */

当我们不知道数组中嵌套了几维数组时,我们可以用Infinity这个参数,帮我们全部展开。

第二问:还有其它的办法吗?因为它们在高版本浏览器并不兼容

方法二:转换为字符串,再把字符串对象用,转换成数组

可以先把多维数组先转换为字符串,再基于,分隔符将字符串对象分割成字符串数组

toString() 扁平化数组

arr = arr.toString();
// "1,2,2,3,4,5,5,6,7,8,9,11,12,12,13,14,10"

arr = arr.toString().split(',');
// ["1", "2", "2", "3", "4", "5", "5", "6", "7", "8", "9", "11", "12", "12", "13", "14", "10"]

arr = arr.toString().split(',').map(item => parseFloat(item));
// [1, 2, 2, 3, 4, 5, 5, 6, 7, 8, 9, 11, 12, 12, 13, 14, 10]

除了上面的方法还有什么方法转换为字符串呢?

JSON.stringify()扁平化数组

arr = JSON.stringify(arr);
// "[[1,2,2],[3,4,5,5],[6,7,8,9,[11,12,[12,13,[14]]]],10]"

arr = JSON.stringify(arr).replace(/(\[|\])/g, '');
// "1,2,2,3,4,5,5,6,7,8,9,11,12,12,13,14,10"

arr = JSON.stringify(arr).replace(/(\[|\])/g, '').split(',').map(item=>parseFloat(item));
// [1, 2, 2, 3, 4, 5, 5, 6, 7, 8, 9, 11, 12, 12, 13, 14, 10]

方法三:循环验证是否为数组

基于数组的some方法,只要数组里面有一项元素是数组就继续循环,扁平数组

核心:[].concat(...arr)

whilte (arr.some(item => Array.isArray(item))) {
 arr = [].concat(...arr);
}

console.log(arr); // [1, 2, 2, 3, 4, 5, 5, 6, 7, 8, 9, 11, 12, 12, 13, 14, 10]

第三问:能自己实现一个 flat 扁平化吗?

先回答:能!!再跟着我分析思路:

如何实现呢,其实思路非常简单:在数组中找到是数组类型的元素,然后将他们展开,这就是flat方法的关键思路

实现思路:

  • 循环数组里的每一个元素
  • 判断该元素是否为数组
    • 是数组的话,继续循环遍历这个元素——数组
    • 不是数组的话,把元素添加到新的数组中

实现流程:

  1. 创建一个空数组,用来保存遍历到的非数组元素
  2. 创建一个循环遍历数组的函数,cycleArray
  3. 取得数组中的每一项,验证Array.isArray()
  • 数组的话,继续循环
  • 非数组的话,添加到新数组中
  1. 返回新数组对象

ES5 实现 flat 扁平化方法

let arr = [
    [1, 2, 2],
    [3, 4, 5, 5],
    [6, 7, 8, 9, [11, 12, [12, 13, [14]]]], 10
];

function myFlat() {
  _this = this; // 保存 this:arr
  let newArr = [];
  // 循环arr中的每一项,把不是数组的元素存储到 newArr中
  let cycleArray = (arr) => {
    for (let i=0; i      let item = arr[i];
      if (Array.isArray(item)) { // 元素是数组的话,继续循环遍历该数组
        cycleArray(item);
        continue;
      } else{
        newArr.push(item); // 不是数组的话,直接添加到新数组中
      }
    }
  }
  cycleArray(_this); // 循环数组里的每个元素
  return newArr; // 返回新的数组对象
}

Array.prototype.myFlat = myFlat;

arr = arr.myFlat(); // [1, 2, 2, 3, 4, 5, 5, 6, 7, 8, 9, 11, 12, 12, 13, 14, 10]

ES6 实现 flat 扁平化方法

const myFlat = (arr) => {
  let newArr = [];
  let cycleArray = (arr) => {
    for(let i = 0; i       let item = arr[i];
      if (Array.isArray(item)) {
        cycleArray(item);
        continue;
      } else {
        newArr.push(item);
      }
    }
  }
  cycleArray(arr);
  return newArr;
}

myFlat(arr); // [1, 2, 2, 3, 4, 5, 5, 6, 7, 8, 9, 11, 12, 12, 13, 14, 10]

第四问:请使用reduce实现flat函数

相信很多面试官都会指定让面试者用reduce方法实现flat函数

其实思路也是一样的,在实现之前,先来看一下

它的核心:[].concat(...arr)

但是它只能将数组元素展开一层,来看下面例子:

let arr2 = [12, 23, [34, 56, [78, 90, 100]]];
[].concat(...arr2);
// [ 12, 23, 34, 56, [ 78, 90, 100 ] ]

细心的同学可以发现[].concat(...arr)只能展开一层数组元素,当有更深层次的,是无法展开的

接下来,我们来看看用reduce怎么实现?

let arr = [12, 23, [34, 56, [78, 90, 100, [110, 120, 130, 140]]]];
const myFlat = arr => {
  return arr.reduce((pre, cur) => {
    return pre.concat(cur);
  }, []);
};
console.log(myFlat(arr));
// [ 12, 23, 34, 56, [ 78, 90, 100, [ 110, 120, 130, 140 ] ] ]

const myFlat = arr => {
  return arr.reduce((pre, cur) => {
    return pre.concat(Array.isArray(cur) ? myFlat(cur) : cur);
  }, []);
};
console.log(myFlat(arr));
// [12, 23, 34, 56, 78, 90, 100, 110, 120, 130, 140]

上面代码中的Array.isArray(cur)myFlat(cur)实际就好比与遍历数组每一项,看它是不是数组元素,

如果是的话,则继续递归遍历,不是的话直接数组合并非数组元素

第五问:使用栈的思想实现flat函数

栈思想: 后进先出的数据结构

实现思路:

不断获取并删除栈中最后一个元素A,判断A是否为数组元素,直到栈内元素为空,全部添加到newArr

  • 是数组,则push到栈中,继续循环栈内元素,直到栈为空
  • 不是数组,则unshift添加到newArr
// 栈思想
function flat(arr) {
  const newArr = [];
  const stack = [].concat(arr);  // 将数组元素拷贝至栈,直接赋值会改变原数组
  //如果栈不为空,则循环遍历
  while (stack.length !== 0) {
    const val = stack.pop(); // 删除数组最后一个元素,并获取它
    if (Array.isArray(val)) {
      stack.push(...val); // 如果是数组再次入栈,并且展开了一层
    } else {
      newArr.unshift(val); // 如果不是数组就将其取出来放入结果数组中
    }
  }
  return newArr;
}

let arr = [12, 23, [34, 56, [78, 90, 100, [110, 120, 130, 140]]]];
console.log(flat(arr));
// [12, 23, 34, 56, 78, 90, 100, 110, 120, 130, 140]

本文总结

看完这篇文章的同学,可以在面试的时候分类,分思想给面试官描述,可以先说我用哪几种思想实现过,它们的写法又分别有什么不同。

最后希望这篇文章可以帮助到大家,感谢阅读。

看完三件事❤

如果你觉得这篇内容对你还蛮有帮助,我想邀请你帮我三个小忙:

  1. 点赞,转发,有你们的 在看,才是我创造的动力。
  2. 关注公众号 前端时光屋,不定期分享原创知识。
  3. 同时可以期待后续文章ing?
fc18af907d0c0cc2323afb0420c72b43.png

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/505112.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

iqc工作职责和工作内容_监理工程师工作职责

1&#xff0e;安全监理员是项目安全生产日常监理工作的主要实施者&#xff0c;代表总监理工程师在项目工程监理过程中行使项目安全生产监理的职责。2&#xff0e;安全监理员应认真贯彻执行《建设工程安全生产管理条例》&#xff0c;贯彻执行劳动保护、安全生产的方针政策、法令…

webservice 实现与his系统对接_[Share] EDI 及其他常见系统对接技术

近期&#xff0c;有客户提及&#xff1a;你们有没有对接技术相关的介绍&#xff0c;不同系统之间的对接技术&#xff0c;现在企业内部系统比较多&#xff0c;有自主开发的&#xff0c;有外部采购的&#xff0c;所以我们想了解一下对接技术相关的信息。小知马不停蹄的做了下功课…

php弱类型漏洞,php代码审计之弱类型引发的灾难

天融信阿尔法实验室 李喆有人说php是世界上最好的语言&#xff0c;这可能是对开发人员来说&#xff0c;确实有这方面的特点&#xff0c;因为它开发起来不像其他语言那样麻烦&#xff0c;就比如&#xff1a;弱类型&#xff0c;它不需要像java等语言那样明确定义数据类型。这给开…

大学计算机基础python第二次作业_第二次python作业-titanic数据练习

原博文 2019-10-14 14:45 − 一、读入titanic.xlsx文件&#xff0c;按照教材示例步骤&#xff0c;完成数据清洗。 titanic数据集包含11个特征&#xff0c;分别是&#xff1a; Survived:0代表死亡&#xff0c;1代表存活Pclass:乘客所持票类&#xff0c;有三种值(1,2,3)Name:乘客…

微小宝公众号排行榜_榜单 广东省技工院校微信公众号排行榜(第51期)

▼2020年10月榜单出炉&#xff01;本期榜单最大看点&#xff0c;莫过于发文33篇的劳模代表——“广东高新技术高级技校”以高达830.49的微信传播指数WCI&#xff0c;荣登第51期广东省技工院校微信公众号排行榜榜首&#xff01;截至本期&#xff0c;实力一向强劲的“广东高新技术…

word公式编辑器_【Word技巧】word使用终极技巧,工程人必会(四)

1、问&#xff1a;Word中怎么在一个英文字母上打对号&#xff1f;答&#xff1a;透明方式插入图片对象&#xff0c;内容是一个√2、问&#xff1a;Word里怎么显示修订文档的状态&#xff1f;文档修订后&#xff0c;改后标记很多&#xff0c;但是在菜单里没有“显示修订最终状态…

加载oracle属性文件,关于属性文件的详细介绍

我们通常会将Java应用的配置参数保存在属性文件中&#xff0c;Java应用的属性文件可以是一个正常的基于key-value对,以properties为扩展名的文件&#xff0c;也可以是XML文件. 在本案例中&#xff0c;將会向大家介绍如何通过Java程序输出这两种格式的属性文件&#xff0c;并介绍…

android 访问服务器sql_XSS 攻击、CSRF 攻击、SQL 注入、流量劫持(DNS 劫持、HTTP 劫持)—— 浏览器安全

今天看了 jsliang 大佬关于网络安全的文章&#xff0c;为了加深一下印象&#xff0c;自己动手写一下。 主要参考文章&#xff1a;网络安全 ——— jsliang XSS攻击 XSS&#xff08;Cross Site Script&#xff09;跨站脚本攻击&#xff0c;指的是向网页注入恶意代码&#xff0c;…

simulink和psim仿真结果不同_在HFSS进行AC耦合电容仿真优化怎么做?

AC耦合电容&#xff0c;也叫DC blocking隔直电容&#xff0c;在几乎所有的高速串行链路中&#xff0c;都可以看到它的身影&#xff0c;它的主要作用是去掉信号中的直流偏置分量&#xff0c;同时让高频分量可以顺利通过&#xff0c;类似于一个高宽带的滤波器。由于电容的焊盘通常…

民生银行 一码付 php,PHP开心码支付免签约第四方支付平台源码修复版

源码说明后台号码admin后台密码123456声明&#xff1a;该源码仅供学习出现&#xff0c;修复者不承担任何责任&#xff0c;下载安装即代表使用者自行承担责任源码安装方法需要服务器开启g11插件PHP5.6&#xff0c;主机用户推荐95云主机&#xff0c;因为已经开启所有扩展插件必须…

oracle主从表分离怎么实时更新数据_高可用数据库UDB主从复制延时的解决

MySQL主从复制的延时一直是业界困扰已久的问题。延时的出现会降低主从读写分离的价值&#xff0c;不利于数据实时性较高的业务使用MySQL。UDB是UCloud推出的云数据库服务&#xff0c;上线已达六年&#xff0c;运营了数以万计的UDB MySQL实例。除了提供高可用、高性能、便捷易用…

vp翻N_VP刀叨叨:如何让G胖给你唱生日歌

VS看起来好凶喵▼ESL欧洲&独联体区VP发推庆祝击败OG昨晚第九个比赛日&#xff0c;OG与VP的比赛无疑是大家关注的焦点&#xff0c;一边是TI双冠王&#xff0c;一边是状态开始回升的俄罗斯毛熊&#xff0c;大家都很期待他们能给我们带来精彩的比赛。不过比赛结果却出乎了不少…

秒后面的单位是什么_为什么兰州马拉松很难跑出好成绩?

如果要评选中国最难PB的马拉松&#xff0c;西北第一马兰州马拉松当之无愧可以排名第一。为什么这么说呢&#xff1f;先来看下今年兰马的一组数据&#xff0c;不管是精英选手还是大众选手&#xff0c;成绩都要比个人PB慢。国内男子冠军是管油胜&#xff0c;成绩为2小时18分58秒&…

surface php老是用不了,surface pro7触摸屏没反应怎么办

发生该问题的原因可能是&#xff1a;有很多可能原因&#xff0c;从校准到硬件或者固件。故障排查可以找到根本原因。1. 清洁屏幕将柔软的无绒布蘸上水或眼镜清洗液来清洁屏幕&#xff0c;但不要直接在屏幕上喷洒液体。2. 重启 Surface注意&#xff1a;你将需要连接键盘或鼠标到…

小优优(u盘歌曲顺序调整)_电脑从U盘启动,这三种方式你知道吗?

Windows 可以运行在数千台不同配置的电脑上, 但安装 Windows 10又是另一回事, 具体取决于你的电脑是否安装了现有的 Windows 10,以及早期版本,像是 Windows7, Windows XP, 或完全不同的操作系统(如 macOS 或 Linux)。大多数情况, 安装系统都依赖于主硬盘HDD或SSD以外的设备启动…

unity vs没有智能提示_Unity博主营地你不可不知的Unity C#代码小技巧

「Unity博主营地第一期」于2019年11月开启&#xff0c;现已收到数百篇原创投稿。每周根据Unity Connect社区反馈&#xff0c;帮助大家发现最优质、最干货、最受欢迎的博文作品。开门见山的说&#xff0c;这篇文章干到挤不出一点水分。文章主要针对Unity初学者&#xff0c;相信读…

python123数值运算_python123中 Hello World的条件输出 和数值运算

描述 获得用户输入的一个整数&#xff0c;参考该整数值&#xff0c;打印输出"Hello World"&#xff0c;要求&#xff1a;‪‬‪‬‪‬‪‬‪‬‮‬‪‬‭‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‫‬‪‬‪‬‪‬‪‬‪‬‮‬‭‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‪‬‪‬‪…

苹果sf字体_苹果UI设计的改变意味着什么?

WWDC虽然已经过去了一段时间&#xff0c;虽然没有什么硬件产品&#xff0c;但还是给我们带来了许多新的惊喜。但我们这篇文章不谈技术问题&#xff0c;只谈苹果的UI变化。因为这可能是近10年来苹果第二次颠覆性的升级&#xff0c;上次还是2013年的iOS7的全面扁平化。从设计的层…

cuda卸载_Ubuntu18.04英伟达显卡驱动、Cuda安装

一、显卡驱动安装1. 准备工作禁用BIOS中的secure boot&#xff0c;因为此方法使用第三方源安装显卡驱动&#xff0c;不禁止secure boot会导致安装的驱动不能使用&#xff0c;禁用也不会有多大安全隐患。2. 禁用nouveau禁用nouveau&#xff0c;这是ubuntu默认使用的开源显卡驱动…

内存条能4+8混插吗?_笔记本内存条双通道提升有多大?实测FORESEE,你知道好处在哪吗...

不知道大家发现了没&#xff0c;最近存储类产品、内存条普遍价格都涨起来了&#xff0c;后悔年前没买内存条给我的暗夜精灵3升升级&#xff0c;至今还插着一根8G的条子&#xff0c;其实日常用也够了。不过&#xff0c;今年打算做做视频&#xff0c;搞搞线上直播&#xff0c;所以…