js 数组从头添加到数组
介绍 (Introduction)
JavaScript includes several functions for working with arrays that go beyond the for
loop. You may have used these functions in your own projects and wondered how they work and why you’d use one over another.
JavaScript包含多个用于处理数组的函数,这些函数超出了for
循环。 您可能在自己的项目中使用了这些功能,并想知道它们是如何工作的以及为什么要一一使用。
A great way to understand how something works is to build your own version from scratch. In this article, you are going to do that by creating your own versions of map
, filter
, sort
, and reduce
from scratch. When you’re done, you’ll have a better understanding of these functions and their uses.
理解某项工作原理的一种好方法是从头开始构建自己的版本。 在本文中,您将通过创建自己的map
, filter
, sort
和reduce
的版本来做到这一点。 完成后,您将对这些功能及其用途有更好的了解。
By combining ES6 Arrow Functions with JavaScript Array functions, you can write extremely powerful and clean code.
通过将ES6箭头函数与JavaScript数组函数结合使用,您可以编写功能强大且简洁的代码。
JavaScript数组方法如何工作 (How JavaScript Array Methods Work)
Let’s start with an example. Let’s say you want to iterate through an array of numbers, increment each element by one, and return the new array. In the past, you would need to do several things to accomplish this:
让我们从一个例子开始。 假设您要遍历数字数组,将每个元素加1,然后返回新数组。 过去,您需要做几件事来完成此任务:
- Initialize a new empty array. 初始化一个新的空数组。
- Iterate through each element in the original array. 遍历原始数组中的每个元素。
- Alter that element and put the altered value into the new array. 更改该元素,然后将更改后的值放入新数组中。
The code would look like this:
代码如下所示:
const arr = [1, 2, 3];
const newArray = [];
for (let i = 0; i < arr.length; i++) {
newArray[i] = arr[i] + 1;
}
return newArray;
But with the built-in map
function, you can accomplish this in a single line of code:
但是,使用内置的map
函数,您可以在一行代码中完成此操作:
return arr.map(element => ++element);
JavaScript Array methods heavily leverage ES6 Arrow Functions.
JavaScript Array方法大量利用ES6箭头函数 。
Each of the Array functions we will cover accept a function as a parameter. They will iterate through each element of the array and call that function to determine what to do with each element. After iterating through each element and calling the callback function, a new array or item will be returned.
我们将介绍的每个Array函数都接受一个函数作为参数。 它们将遍历数组的每个元素,并调用该函数以确定如何处理每个元素。 遍历每个元素并调用回调函数后,将返回一个新的数组或项目。
先决条件 (Prerequisites)
To follow this tutorial locally, you will need an editor (such as Visual Studio Code) and a sandbox environment extension (such as Quokka.js).
要在本地遵循本教程,您将需要一个编辑器(例如Visual Studio Code )和一个沙箱环境扩展(例如Quokka.js )。
To follow the tutorial online, you can use CodePen or CodeSandbox.
要在线阅读本教程,可以使用CodePen或CodeSandbox 。
第1步-实施地图 (Step 1 — Implementing Map)
map
iterates through each element, transforms it in some way, adds it to a new array, and returns the new array.
map
遍历每个元素,以某种方式对其进行转换,将其添加到新数组,然后返回新数组。
Warning: In this article, you’re going to extend JavaScript global objects with custom functions. This is for educational purposes only, as this practice has the potential to introduce side effects in production code.
警告 :在本文中,您将使用自定义函数扩展JavaScript全局对象。 这仅出于教育目的,因为这种做法有可能在生产代码中引入副作用。
JavaScript array functions are part of the Array prototype, similar to functions on a class in Java, for example. To override them, you can assign a new function to Array.prototype
.
JavaScript数组函数是Array原型的一部分,类似于Java中类的函数。 要覆盖它们,可以为Array.prototype
分配一个新函数。
Let’s create a new function and assign it to Array.prototype.mapFromScratch
:
让我们创建一个新函数并将其分配给Array.prototype.mapFromScratch
:
const myCustomMapFunction = function(callback) {
console.log('My Custom Map Function!');
}
Array.prototype.mapFromScratch = myCustomMapFunction;
const arr = [1, 2, 3];
arr.mapFromScratch();
If you run this code, you will see the log message in the console:
如果运行此代码,您将在控制台中看到日志消息:
Output
My Custom Map Function!
Now, add the for
loop and print out each element. Due to the array itself calling the method, you get access to that array by referencing this
:
现在,添加for
循环并打印出每个元素。 由于数组本身调用该方法,因此您可以通过引用this
来访问该数组:
const myCustomMapFunction = function(callback) {
console.log('My Custom Map Function!');
// 'this' refers to the array
for (let i = 0; i < this.length; i++) {
console.log(this[i]);
}
}
Now, perform any required transformation by calling the callback function. When you do, you will pass it the current element and the current index:
现在,通过调用回调函数执行所有必需的转换。 完成后,您将向其传递当前元素和当前索引:
const myCustomMapFunction = function(callback) {
console.log('My Custom Map Function!');
// 'this' refers to the array
for (let i = 0; i < this.length; i++) {
const transformedElement = callback([this[i], i);
}
}
Finally, add the transformed elements to a new array and return that array.
最后,将转换后的元素添加到新数组中并返回该数组。
const myCustomMapFunction = function(callback) {
console.log('My Custom Map Function!');
const newArray = [];
// 'this' refers to the array
for (let i = 0; i < this.length; i++) {
newArray[i] = callback(this[i], i);
}
return newArray;
}
Let’s take a look of your rewritten function in action by testing it with a function that will increment each value in the array:
让我们通过使用将增加数组中每个值的函数进行测试来看看重写后的函数的作用:
// arr = [1, 2, 3]
// expected = [2, 3, 4]
console.log(arr.mapFromScratch((element) => ++element));
You will receive the following output:
您将收到以下输出:
Output
My Custom Map Function!
[2, 3, 4]
In this step you implemented a custom map
function. Next, let’s explore implementing a filter
function.
在此步骤中,您实现了自定义map
功能。 接下来,让我们探索实现filter
功能。
第2步-实施过滤器 (Step 2 — Implementing Filter)
The filter
function returns a new array of elements filtered from the original array.
filter
函数返回一个从原始数组中过滤出来的元素的新数组。
Let’s create a new function and assign it to Array.prototype.filterFromScratch
:
让我们创建一个新函数并将其分配给Array.prototype.filterFromScratch
:
const myCustomFilterFunction = function(callback) {
console.log('My Custom Filter Function!');
}
Array.prototype.filterFromScratch = myCustomFilterFunction;
const arr = [1, 2, 3];
arr.filterFromScratch();
Now, set up the for
loop to iterate through each element:
现在,设置for
循环以遍历每个元素:
const myCustomFilterFunction = function(callback) {
console.log('My Custom Filter Function!');
const newArray = [];
for (let i = 0; i < this.length; i++) {
console.log(this[i]);
}
}
Inside of the for
loop, you need to decided whether or not to add each element to the new array. This is the purpose of the callback function, so you use it to conditionally add each element. If the return value is true
, push the element on to the return array:
在for
循环内部,您需要确定是否将每个元素添加到新数组中。 这是回调函数的目的,因此您可以使用它有条件地添加每个元素。 如果返回值为true
,则将元素推到返回数组上:
const myCustomFilterFunction = function(callback) {
console.log('My Custom Filter Function!');
const newArray = [];
for (let i = 0; i < this.length; i++) {
if (callback(this[i])) {
newArray.push(this[i]);
}
}
return newArray;
}
Let’s take a look at your rewritten function in action by testing it with a function that will display values that are greater than 1
:
让我们通过使用一个显示大于1
值的函数来测试您重写的函数的作用:
// arr = [1, 2, 3]
// expected = [2, 3]
console.log(arr.filterFromScratch((element) => element > 1));
You will receive the following output:
您将收到以下输出:
Output
My Custom Filter Function!
[2, 3]
With that, you have implemented a custom filter
function. Next you will work with the sort
function.
这样,您就实现了自定义filter
功能。 接下来,您将使用sort
功能。
步骤3 —实施排序 (Step 3 — Implementing Sort)
The sort
function returns a sorted array from the original array.
sort
函数从原始数组返回已排序的数组。
Let’s create a new function and assign it to Array.prototype.sortFromScratch
:
让我们创建一个新函数并将其分配给Array.prototype.sortFromScratch
:
const myCustomSortFunction = function(callback) {
console.log('My Custom Sort Function!');
}
Array.prototype.sortFromScratch = myCustomSortFunction;
const arr = [3, 2, 1];
arr.sortFromScratch();
We are going to be using Bubble Sort for this sort implementation. Here’s the approach we will take:
我们将使用Bubble Sort进行这种排序。 我们将采用以下方法:
- Repeatedly iterate through items in array. 重复遍历数组中的项目。
- Compare adjacent items and swap if they are not in order. 比较相邻的项目,如果顺序不对,则交换它们。
- After iterating through the array enough times to make each comparison, the array is sorted. 在遍历数组足够多次以进行每个比较之后,对数组进行排序。
With Bubble Sort, you have to iterate through the array fully once for each element in the array. This calls for a nested for
loop where the inner loop iterates through stopping one short of the final element, so let’s add that now.
使用冒泡排序,您必须对数组中的每个元素完全遍历数组一次。 这需要一个嵌套的for
循环,其中,内部循环通过停止最后一个元素的间隔来进行迭代,因此现在就添加它。
Note: This is intended for educational purposes and isn’t an efficient method for sorting.
注意 :这是出于教育目的,不是有效的分类方法。
const myCustomSortFunction = function(callback) {
console.log('My Custom Sort Function!');
const newArray = [];
for (let i = 0; i < newArray.length; i++) {
for (let j = 0; j < newArray.length - 1; j++) {
}
}
}
You also don’t want to alter the original array. To avoid this, you can copy the original array into the new array using the Spread Operator.
您也不想更改原始数组。 为避免这种情况,您可以使用Spread Operator将原始数组复制到新数组中。
const myCustomSortFunction = function(callback) {
console.log('My Custom Sort Function!');
const newArray = [...this];
for (let i = 0; i < newArray.length; i++) {
for (let j = 0; j < newArray.length - 1; j++) {
}
}
}
The callback function takes two parameters, the current element and the next element, and will return whether or not they are in order. In our case, if the callback function returns a number greater than 0
, we want to swap the two elements.
回调函数采用两个参数,当前元素和下一个元素,并将返回它们是否按顺序排列。 在我们的例子中,如果回调函数返回的数字大于0
,我们想交换两个元素。
const myCustomSortFunction = function(callback) {
console.log('My Custom Sort Function!');
const newArray = [...this];
for (let i = 0; i < newArray.length; i++) {
for (let j = 0; j < newArray.length - 1; j++) {
if (callback(newArray[j], newArray[j + 1]) > 0) {
// swap the elements
}
}
}
}
To swap the elements, you make a copy of one, replace the first one, and then replace the second one with the copy. When finished, it returns the newly sorted array.
要交换元素,请制作一个副本,替换第一个,然后用副本替换第二个。 完成后,它将返回新排序的数组。
const myCustomSortFunction = function(callback) {
console.log('My Custom Sort Function!');
const newArray = [...this];
for (let i = 0; i < newArray.length; i++){
for (let j = 0; j < newArray.length - 1; j++) {
if (callback(newArray[j], newArray[j + 1]) > 0) {
const temp = newArray[j + 1];
newArray[j + 1] = newArray[j];
newArray[j] = temp;
}
}
}
// array is sorted
return newArray;
}
Let’s take a look of your rewritten function in action by testing it with a function that quicksorts from low to high:
通过使用从低到高快速排序的功能对其进行测试,让我们看一下重写后的功能的实际作用:
// arr = [3, 2, 1]
// expected = [1, 2, 3]
console.log(arr.sortFromScratch((current, next) => current - next));
You will receive the following output:
您将收到以下输出:
Output
My Custom Sort Function!
[1, 2, 3]
Now that you’ve created a custom sort
function, you’re ready to move on to implementing a reduce
function.
现在,您已经创建了一个自定义sort
函数,您可以继续执行reduce
函数了。
第4步-实施Reduce (Step 4 — Implementing Reduce)
The reduce
function iterates through each element and returns one single value.
reduce
函数遍历每个元素并返回一个单个值。
reduce
does not return a new array like the other functions. It actually “reduces” the elements in an array to one final value: a number, a string, or an object. One of the most common reasons for using reduce
is for when you want to sum up all the elements in an array of numbers.
reduce
不会像其他函数一样返回新数组。 它实际上将数组中的元素“减少”为一个最终值:数字,字符串或对象。 使用reduce
的最常见原因之一是当您想对数字数组中的所有元素求和时。
Let’s create a new function and assign it to Array.prototype.reduceFromScratch
:
让我们创建一个新函数并将其分配给Array.prototype.reduceFromScratch
:
const myCustomReduceFunction = function(callback) {
console.log('My Custom Reduce Function!');
}
Array.prototype.reduceFromScratch = myCustomReduceFunction;
const arr = [1, 2, 3];
arr.reduceFromScratch();
For reduce
to return one final value, it needs a starting value to work with. The callback function that the user passes along will determine how to update this accumulator based on each element of the array and return it at the end. The callback function must return the updated accumulator.
为了reduce
返回一个最终值,需要使用一个起始值。 用户传递的回调函数将根据数组的每个元素确定如何更新此累加器 ,并在最后将其返回。 回调函数必须返回更新的累加器。
Add your for
loop now, and make a call to the callback function. The return value becomes the new accumulator. After the loop ends, you return the accumulator.
现在添加您的for
循环,并调用回调函数。 返回值将成为新的累加器。 循环结束后,您将返回累加器。
const myCustomReduceFunction = function(callback, accumulator) {
console.log('My Custom Reduce Function!');
for (let i = 0; i < this.length; i++) {
accumulator = callback(accumulator, this[i]);
}
return accumulator;
}
Let’s take a look of your rewritten function in action by testing it with a function that sums up the contents of an array:
让我们看一下您重写后的函数的运行情况,方法是使用一个总结数组内容的函数进行测试:
// arr = [1, 2, 3]
// expected = 6
console.log(arr.reduceFromScratch((accumulator, element) => accumulator + element, 0));
Output
My Custom Reduce Function!
6
结论 (Conclusion)
JavaScript’s array functions are extremely useful. In this tutorial, you reimplemented the array functions to get a better understanding of how they work so you can use them more effectively.
JavaScript的数组函数非常有用。 在本教程中,您重新实现了数组函数,以更好地了解它们的工作方式,从而可以更有效地使用它们。
js 数组从头添加到数组