• 主页
  • 关于
    • Yancx的个人网站 photo

      Yancx的个人网站

      欢迎来到我的博客

    • 个人简历
    • Email
    • Github
    • Weibo
  • 文章
    • 所有文章
    • 所有标签
  • 项目
返回
关于数组的一些笔记
  2018年02月18日

数组的复制

数组是复合的数据类型,直接复制的话,只是复制了指向底层数据结构的指针,而不是克隆一个全新的数组。

var a1 = [1,2,3];
var a2 = a1;

a2[0] = 3;
console.log(a1);
// 打印出-> [3,2,3]

如上,复制后改变a2的数据,a1也会跟着改变。因为只是复制了指向数据的指针,实际a1和a2在内存中是同一个数据。
解决方法

  • ES5方法 -> 利用Array的concat()方法
    concat() 方法用于连接数组。 该方法不会改变现有的数组,而仅仅会 返回被连接数组的一个副本。
var a1 = [1,2,3];
var a2 = a1.concat();

a2[0] = 3;
console.log(a1);
// 打印出-> [1,2,3]
  • ES6方法 -> 利用扩展运算符(…)
    扩展运算符以三个点的形式出现 … 可以将数组或者对象里面的值展开。
    const a1 = [1, 2,3];
    const a2 = [...a1];
    

数组的合并

扩展运算符提供了数组合并的新写法。

const arr1 = ['a', 'b'];
const arr2 = ['c'];
const arr3 = ['d', 'e'];

// ES5 的合并数组
arr1.concat(arr2, arr3);
console.log(arr1);
// [ 'a', 'b', 'c', 'd', 'e' ]

// ES6 的合并数组
[...arr1, ...arr2, ...arr3]
// [ 'a', 'b', 'c', 'd', 'e' ]

不过,这两种方法都是浅拷贝,使用的时候需要注意。

const a1 = [{ foo: 1 }];
const a2 = [{ bar: 2 }];

const a3 = a1.concat(a2);
const a4 = [...a1, ...a2];

a3[0] === a1[0] // true
a4[0] === a1[0] // true

上面代码中,a3和a4是用两种不同方法合并而成的新数组,但是它们的成员都是对原数组成员的引用,这就是浅拷贝。如果修改了原数组的成员,会同步反映到新数组。

利用ES6的set数据结构进行数组去重

ES6 提供了新的数据结构 Set。它类似于数组,但是成员的值都是唯一的,没有重复的值。

[...new Set(array)];
// 或者
Array.from(new Set(array));

利用ES6数组的flat()方法将多维数组转为一维数组

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

[1, 2, [3, 4]].flat()
// [1, 2, 3, 4]

上面代码中,原数组的成员里面有一个数组,flat()方法将子数组的成员取出来,添加在原来的位置。

flat()默认只会“拉平”一层,如果想要“拉平”多层的嵌套数组,可以将flat()方法的参数写成一个整数,表示想要拉平的层数,默认为1。

[1, 2, [3, [4, 5]]].flat()
// [1, 2, 3, [4, 5]]

[1, 2, [3, [4, 5]]].flat(2)
// [1, 2, 3, 4, 5]

上面代码中,flat()的参数为2,表示要“拉平”两层的嵌套数组。

如果不管有多少层嵌套,都要转成一维数组,可以用Infinity关键字作为参数。

[1, [2, [3]]].flat(Infinity)
// [1, 2, 3]

如果原数组有空位,flat()方法会跳过空位。

[1, 2, , 4, 5].flat()
// [1, 2, 4, 5]


数组JS前端基础