如何在JavaScript中克隆数组

JavaScript has many ways to do anything. I’ve written on 10 Ways to Write pipe/compose in JavaScript, and now we’re doing arrays.

JavaScript有许多方法可以执行任何操作。 我已经写了10种用JavaScript编写管道/组合的方法 ,现在我们正在做数组。

1.传播算子(浅副本) (1. Spread Operator (Shallow copy))

Ever since ES6 dropped, this has been the most popular method. It’s a brief syntax and you’ll find it incredibly useful when using libraries like React and Redux.

自从ES6删除以来,这一直是最受欢迎的方法。 这是一个简短的语法,在使用像React和Redux这样的库时,您会发现它非常有用。

numbers = [1, 2, 3];
numbersCopy = [...numbers];

Note: This doesn’t safely copy multi-dimensional arrays. Array/object values are copied by reference instead of by value.

注意:这不能安全地复制多维数组。 数组/对象值是通过引用而不是value复制的。

This is fine

这可以

numbersCopy.push(4);
console.log(numbers, numbersCopy);
// [1, 2, 3] and [1, 2, 3, 4]
// numbers is left alone

This is not fine

这样不好

nestedNumbers = [[1], [2]];
numbersCopy = [...nestedNumbers];

numbersCopy[0].push(300);
console.log(nestedNumbers, numbersCopy);
// [[1, 300], [2]]
// [[1, 300], [2]]
// They've both been changed because they share references

2. Good Old for()循环(浅副本) (2. Good Old for() Loop (Shallow copy))

I imagine this approach is the least popular, given how trendy functional programming’s become in our circles.

我想这种方式是流行的,时髦给出函数式编程在我们的圈子怎么成了。

Pure or impure, declarative or imperative, it gets the job done!

纯净或不纯净,陈述性或命令性,就可以完成工作!

numbers = [1, 2, 3];
numbersCopy = [];

for (i = 0; i < numbers.length; i++) {
  numbersCopy[i] = numbers[i];
}

Note: This doesn’t safely copy multi-dimensional arrays. Since you’re using the = operator, it’ll assign objects/arrays by reference instead of by value.

注意:这不能安全地复制多维数组。 由于使用的是=运算符,它将按引用而不是按分配对象/数组。

This is fine

这可以

numbersCopy.push(4);
console.log(numbers, numbersCopy);
// [1, 2, 3] and [1, 2, 3, 4]
// numbers is left alone

This is not fine

这样不好

nestedNumbers = [[1], [2]];
numbersCopy = [];

for (i = 0; i < nestedNumbers.length; i++) {
  numbersCopy[i] = nestedNumbers[i];
}

numbersCopy[0].push(300);
console.log(nestedNumbers, numbersCopy);
// [[1, 300], [2]]
// [[1, 300], [2]]
// They've both been changed because they share references

3. Good Old while()循环(浅副本) (3. Good Old while() Loop (Shallow copy))

Same as for—impure, imperative, blah, blah, blah…it works! ?

for -impure,势在必行,等等,等等,等等...它的作品! ?

numbers = [1, 2, 3];
numbersCopy = [];
i = -1;

while (++i < numbers.length) {
  numbersCopy[i] = numbers[i];
}

Note: This also assigns objects/arrays by reference instead of by value.

注意:这还会通过引用而不是value分配对象/数组。

This is fine

这可以

numbersCopy.push(4);
console.log(numbers, numbersCopy);
// [1, 2, 3] and [1, 2, 3, 4]
// numbers is left alone

This is not fine

这样不好

nestedNumbers = [[1], [2]];
numbersCopy = [];

i = -1;

while (++i < nestedNumbers.length) {
  numbersCopy[i] = nestedNumbers[i];
}

numbersCopy[0].push(300);
console.log(nestedNumbers, numbersCopy);
// [[1, 300], [2]]
// [[1, 300], [2]]
// They've both been changed because they share references

4. Array.map(浅副本) (4. Array.map (Shallow copy))

Back in modern territory, we’ll find the map function. Rooted in mathematics, map is the concept of transforming a set into another type of set, while preserving structure.

回到现代领域,我们将找到map函数。 map 起源于数学 ,它是在保留结构的同时将集合转换为另一种类型的集合的概念。

In English, that means Array.map returns an array of the same length every single time.

用英语来说,这意味着Array.map返回相同长度的数组。

To double a list of numbers, use map with a double function.

要将数字列表加倍,请使用带有double函数的map

numbers = [1, 2, 3];
double = (x) => x * 2;

numbers.map(double);
克隆呢? (What about cloning??)

True, this article’s about cloning arrays. To duplicate an array, just return the element in your map call.

没错,本文是关于克隆数组的。 要复制数组,只需在map调用中返回元素即可。

numbers = [1, 2, 3];
numbersCopy = numbers.map((x) => x);

If you’d like to be a bit more mathematical, (x) => x is called identity. It returns whatever parameter it’s been given.

如果您想更加数学化, (x) => x称为identity 。 它返回给定的任何参数。

map(identity) clones a list.

map(identity)克隆一个列表。

identity = (x) => x;
numbers.map(identity);
// [1, 2, 3]

Note: This also assigns objects/arrays by reference instead of by value.

注意:这还会通过引用而不是通过value分配对象/数组。

5. Array.filter(浅拷贝) (5. Array.filter (Shallow copy))

This function returns an array, just like map, but it’s not guaranteed to be the same length.

该函数返回一个数组,就像map一样,但是不能保证长度相同。

What if you’re filtering for even numbers?

如果您要过滤偶数数怎么办?

[1, 2, 3].filter((x) => x % 2 === 0);
// [2]

The input array length was 3, but the resulting length is 1.

输入数组的长度为3,但结果长度为1。

If your filter's predicate always returns true, however, you get a duplicate!

如果您的filter的谓词始终返回true ,那么您将得到一个重复项!

numbers = [1, 2, 3];
numbersCopy = numbers.filter(() => true);

Every element passes the test, so it gets returned.

每个元素均通过测试,因此将其返回。

Note: This also assigns objects/arrays by reference instead of by value.

注意:这还会通过引用而不是value分配对象/数组。

6. Array.reduce(浅副本) (6. Array.reduce (Shallow copy))

I almost feel bad using reduce to clone an array, because it’s so much more powerful than that. But here we go…

使用reduce克隆数组几乎让我感到难过,因为它的功能要强大得多。 但是,我们开始…

numbers = [1, 2, 3];

numbersCopy = numbers.reduce((newArray, element) => {
  newArray.push(element);

  return newArray;
}, []);

reduce transforms an initial value as it loops through a list.

当它循环遍历列表时, reduce转换初始值。

Here the initial value is an empty array, and we’re filling it with each element as we go. That array must be returned from the function to be used in the next iteration.

这里的初始值是一个空数组,我们将在每个元素中填充它。 该数组必须从函数中返回,以在下一次迭代中使用。

Note: This also assigns objects/arrays by reference instead of by value.

注意:这还会通过引用而不是value分配对象/数组。

7. Array.slice(浅拷贝) (7. Array.slice (Shallow copy))

slice returns a shallow copy of an array based on the provided start/end index you provide.

slice根据您提供的开始/结束索引返回数组的浅表副本。

If we want the first 3 elements:

如果我们想要前三个元素:

[1, 2, 3, 4, 5].slice(0, 3);
// [1, 2, 3]
// Starts at index 0, stops at index 3

If we want all the elements, don’t give any parameters

如果我们需要所有元素,请不要提供任何参数

numbers = [1, 2, 3, 4, 5];
numbersCopy = numbers.slice();
// [1, 2, 3, 4, 5]

Note: This is a shallow copy, so it also assigns objects/arrays by reference instead of by value.

注意:这是一个浅表副本,因此它也按引用而不是按分配对象/数组。

8. JSON.parse和JSON.stringify(深复制) (8. JSON.parse and JSON.stringify (Deep copy))

JSON.stringify turns an object into a string.

JSON.stringify将对象转换为字符串。

JSON.parse turns a string into an object.

JSON.parse将字符串转换为对象。

Combining them can turn an object into a string, and then reverse the process to create a brand new data structure.

将它们组合在一起可以将一个对象变成一个字符串,然后逆转该过程以创建一个全新的数据结构。

Note: This one safely copies deeply nested objects/arrays!

注意:此 安全复制深层嵌套的对象/数组

nestedNumbers = [[1], [2]];
numbersCopy = JSON.parse(JSON.stringify(nestedNumbers));

numbersCopy[0].push(300);
console.log(nestedNumbers, numbersCopy);

// [[1], [2]]
// [[1, 300], [2]]
// These two arrays are completely separate!

9. Array.concat(浅副本) (9. Array.concat (Shallow copy))

concat combines arrays with values or other arrays.

concat将数组与值或其他数组组合。

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

If you give nothing or an empty array, a shallow copy’s returned.

如果不提供任何内容或提供空数组,则返回浅表副本。

[1, 2, 3].concat(); // [1, 2, 3]
[1, 2, 3].concat([]); // [1, 2, 3]

Note: This also assigns objects/arrays by reference instead of by value.

注意:这还会通过引用而不是value分配对象/数组。

10. Array.from(浅副本) (10. Array.from (Shallow copy))

This can turn any iterable object into an array. Giving an array returns a shallow copy.

这可以将任何可迭代对象转换为数组。 提供数组将返回浅表副本。

numbers = [1, 2, 3];
numbersCopy = Array.from(numbers);
// [1, 2, 3]

Note: This also assigns objects/arrays by reference instead of by value.

注意:这还会通过引用而不是通过value分配对象/数组。

结论 (Conclusion)

Well, this was fun ?

好吧,这很有趣吗?

I tried to clone using just 1 step. You’ll find many more ways if you employ multiple methods and techniques.

我尝试仅用1个步骤进行克隆。 如果您采用多种方法和技术,则会发现更多方法。

翻译自: https://www.freecodecamp.org/news/how-to-clone-an-array-in-javascript-1d3183468f6a/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值