作为前端你需要知道的七个数组处理方式

原文地址:https://juejin.cn/post/6921666247226556423

1、Arrar.map()

每当你使用 .map() 方法,会创建出一个基于原数组更改过的新数组。 .map() 方法会提供一个函数用以循环遍历(按顺序调用)原数组中的每个元素并改变他们。
如果你想改变数组中所有元素并存于一个新数组, .map() 方法将是你的选择。
假设我们有一个汽车品牌的数组:
假设我们有一个汽车品牌的数组:

const cars = ["Porsche", "Audi", "BMW", "Volkswagen"];
复制代码

当然,我们认为所有汽车都非常酷,并希望添加一些描述文字。我们可以使用 .map()方法做到:

const coolCars = cars.map(car => `${car} is a pretty cool car brand!`);

// Result:
["Porsche is a pretty cool car brand!", "Audi is a pretty cool car brand!", "BMW is a pretty cool car brand!", "Volkswagen is a pretty cool car brand!"];
复制代码
A JavaScript code block showing how the map method is used to create a new, modified array of the original one.

这里, .map() 方法就用来创建出了一个新的、更改过的数组。

太棒了! .map()方法创建了一个新数组,并将描述文本添加到了每个元素中。

更棒的是,我们可用 .map() 方法处理包含对象的数组。

举个例子,我们有一些价格不含税的汽车,然后使用 .map() 添加含税的价格。

const carsWithPrice = [
  {brand: "Porsche", price: 100000},
  {brand: "Audi", price: 80000}
];
const carsWithPriceAndTax = cars.map(carObject => {
  return {
    // Return the original car object
    ...carObject,
    // but also add a new value containing the price with tax
    priceWithTax: carObject.price * 1.2
  }
});

// Result:
[
  {brand: "Porsche", price: 100000, priceWithTax: 120000},
  {brand: "Audi", price: 80000, priceWithTax: 96000}
];
复制代码
JS code block showing how to use the .map() method to create a new array containing the price with tax

总而言之,.map()方法是创建新数组,修改其内容并保持原始数组完整的一种极其通用的方法。

何时用 Array.map()?

当您想要修改现有数组的内容,并将结果存储为新(数组)变量时。


2. Array.filter()

你几乎可以猜到该方法会做什么。

.filter() 方法允许你根据某个特定的条件来获取数组中的元素。

就像 .map()方法一样, .filter() 方法将返回一个新数组,并保留原始数组。

还是用汽车来举例,我们根据汽车价格高于某个特定值来过滤数组。

这里,我们有如下汽车(变量/参数):

const cars = [
  {brand: "Porsche", price: 100000},
  {brand: "Audi", price: 80000},
  {brand: "Toyota", price: 30000}
];
复制代码

现在,假设我们设定超过 40,000 即为昂贵(expensive)。

我们可使用 .filter() 方法来过滤出所有 "cheap" 和 "expensive" 的汽车为两个不同数组。

const expensiveCars = cars.filter(car => car.price >= 40000);
const cheapCars = cars.filter(car => car.price < 40000);

// Result - Expensive Cars
[
  {brand: "Porsche", price: 100000},
  {brand: "Audi", price: 80000}
];

// Result - Cheap Cars
[
  {brand: "Toyota", price: 30000}
];
复制代码
JS code block showing how to use the filter method to filter cheap/expensive cars from an array.

检查数组中的每个元素是否符合条件,如通过测试,则将其返回到新数组中 —— 太棒了!

何时用 Array.filter()?

当您要从数组中去除不符合特定条件/规则的元素时。


3. Array.reduce()

现在讲的这个理解上可能会有些棘手。

简单来说,数组调用 .reduce() ,会对数组中的每个元素执行一个函数,累计处理其返回为单个值。

.reduce() 方法将回调函数作为其第一个传参,可选的初始化值作为其第二个传参(若无初始值,则将使用数组中的第一个元素)。回调函数提供了 accumulatorcurrentValue 两个参数来进行累计处理。

我知道这可能有点复杂,但是没关系。

这里有个简单的例子来展示下 .reduce() 方法的使用:

假设我们要获取一下数组中所有数字的总和。

const numbers = [13, 65, 29, 81, 47];
复制代码

We can then use the .reduce() method to add all these values together.

const total = numbers.reduce((accumulator, currentValue) => accumulator + currentValue, 0);

// Result - Total:
235
复制代码
JS code block showing how to use the reduce method to add up all values of an array.

以上,使用 reduce 方法将数组的所有值相加。

另外, .reduce() 方法可用于展开(多维)数组。有不少方式可以做到这一点,这是其中一种。

const flattened = [[0, 1], [2, 3], [4, 5]].reduce(
  ( accumulator, currentValue ) => accumulator.concat(currentValue),
  []
)

// Result - Flattened:
[0, 1, 2, 3, 4, 5]
复制代码
JS code block showing how to use the reduce method to flatten an array.

何时用 Array.reduce()?

当您想要通过操纵数组的值将数组转换为单个值时。


4. Array.forEach()

Ah,这个可是经典。

.forEach() 方法就和常规的 for 循环非常相似。

它会循环遍历某一个元素并在其上执行一个函数。 .forEach() 方法的第一个传参是回调函数,这个回调函数包含循环的当前值和索引。

用我们的车车来看以下示例:

const cars = [
  {brand: "Porsche", price: 100000},
  {brand: "Audi", price: 80000},
  {brand: "Toyota", price: 30000}
];
复制代码

我们可以循环并打印出一句话,包含品牌名称和汽车价格。

cars.forEach(car => {
  console.log(`The ${car.brand} will cost you ${car.price} before taxes`);
});

// Result:
"The Porsche will cost you 100000 before taxes"
"The Audi will cost you 80000 before taxes"
"The Toyota will cost you 30000 before taxes"
复制代码
JS code block showing how to use the forEach method to loop over all cars and log text showing its brand and price.

何时用 Array.forEach()?

当你想简单遍历所有数组元素(并执行函数),而无需构造新数组时。


5. Array.find()

.find() 方法看上去非常像之前看到的 .filter() 方法。

就像 .filter() 方法一样,你可以传递一个条件,该条件能匹配出(符合该条件的)数组元素值。

两者的区别在于, .find() 将返回与条件匹配的第一个元素。

以汽车示例为例,让我们使用.find() 方法获得数组中遇到的第一辆昂贵的汽车。

const cars = [
  {brand: "Porsche", price: 100000},
  {brand: "Audi", price: 80000},
  {brand: "Toyota", price: 30000}
];
const expensiveCar = cars.find(car => car.price >= 40000);

// Result - Expensive Car:
{brand: "Porsche", price: 100000}
复制代码
JS code block showing how to use the find method to find the first “expensive” car in an array.

何时用 Array.find()?

当你需要获取数组中满足特定测试的第一个元素时。


6. Array.every()

也许你已经可以猜到此方法会做什么。

.every() 方法将检查数组中的每个元素是否通过提供的条件。

如果所有数组元素通过了这个条件,会返回 true 。如果没有,会返回 false

举例说明,我们可以使用.every() 方法来检测是否所有汽车实在近五年内制造的。

const cars = [
  {brand: "Porsche", price: 100000, builtIn: 2018},
  {brand: "Audi", price: 80000, builtIn: 2019},
  {brand: "Toyota", price: 30000, builtIn: 2019}
];
const carsYoungerThanFiveYears = cars.every(car => car.builtIn >= 2016);

// Result - Younger than 5 Years:
true
复制代码
JS code block showing how to use the every method to determine if all cars are built within 5 years.

何时用 Array.every()?

当您要确认数组的每个元素是否都通过显式定义的条件时。


7. Array.some()

.some() 方法类似 .every() 方法,但是不同于所有元素都需通过测试,存在至少一个元素通过测试,该方法就会返回 true。

.some() 方法如果找到了一个满足条件的数组元素,就会停止并返回 true。但如果遍历之后仍未找到(满足条件的),则返回 false。

再来看下我们的车车数组,但是这次我们来查下是否有车车龄超过 5年。

const cars = [
  {brand: "Porsche", price: 100000, builtIn: 2018},
  {brand: "Audi", price: 80000, builtIn: 2019},
  {brand: "Toyota", price: 30000, builtIn: 2019}
];
const carsOlderThanFiveYears = cars.some(car => car.builtIn < 2016);

// Result - Older than 5 Years:
false
复制代码
JS code block showing how to use the some method to check if any of the cars is older than 5 years.

何时用 Array.some()?

当您要确认数组中是否存在元素能通过显式定义的条件时。

总结

🤩 JavaScript 给我们提供了很多处理数组的不同方法。使用这些方法,你将能提升 JS 开发技能,并使代码库更具可维护性。

😌 也许你再也不会碰 for 循环了。

我希望你今天能学到一些新东西。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,457评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,837评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,696评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,183评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,057评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,105评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,520评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,211评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,482评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,574评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,353评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,213评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,576评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,897评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,174评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,489评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,683评论 2 335

推荐阅读更多精彩内容