资讯专栏INFORMATION COLUMN

在项目实践中用更优雅的方式处理数组问题

joy968 / 1502人阅读

在最近的项目中,遇到了比较多处理数组的场景,比如要对数组里面某个元素的某一个字段进行抽取归类,或者判断数组当中的某个元素是否符满足判断条件等。

网上关于使用ES5新的的API来代替for循环的文章已经非常多,它们有的详细讨论了API的用法,有的详细分析各自的性能,还有的整理了使用中的注意事项。因此,本文不再对这些API的详细使用方式进行赘述,仅仅从个人角度出发,整理归纳一些在项目实践中遇到的能够更加优雅处理数组遍历的例子。

1、使用Set处理数组去重和元素剔除问题

Set是es6新增的一种数据结构,它和数组非常相似,但是成员的值都是唯一的,没有重复的值。它提供了4个语义化的API:


add(value):添加某个值,返回Set结构本身。

delete(value):删除某个值,返回一个布尔值,表示删除是否成功。

has(value):返回一个布尔值,表示该值是否为Set的成员。

clear():清除所有成员,没有返回值。

参考自@阮一峰 老师的《ECMAScript 6 入门》

那么我们可以用Set来干嘛呢?

第一个用法,数组去重。对于一个一维数组,我们可以先把它转化成Set,再配合...解构运算符重新转化为数组,达到去重的目的。请看例子:

const arr = [1, 1, 2, 2, 3, 4, 5, 5]

const newArr = [...new Set(arr)]

console.log(newArr)

// [1, 2, 3, 4, 5]

值得注意的是,这个方法不能对元素为“对象”的数组奏效:

const arr = [{ name: "Alice", age: 12 }, { name: "Alice", age: 12 }, { name: "Bob", age: 13 }]

const newArr = [...new Set(arr)]

console.log(newArr)

// [{ name: "Alice", age: 12 }, { name: "Alice", age: 12 }, { name: "Bob", age: 13 }]

这是因为Set判断元素是否重复的办法类似于===运算符,两个对象总是不相等的。

除了去重,Set提供的delete()方法也是非常实用。在以往的做法中,如果要删除数组中指定的元素,我们需要先获取该元素所在下标,然后通过splice()方法去删除对应下标的元素,在理解上容易引起混乱:

// 我想删除数组当中值为2的元素
const arr = [1, 2, 3]
const index = arr.indexOf(2)
if (index !== -1) {
    arr.splice(index, 1)
}

console.log(arr)

// [1, 3]

使用Set就清晰多了:

const arr = [1, 2, 3]
const set = new Set(arr)
set.delete(2)
arr = [...set]

console.log(arr)

// [1, 3]
2、 使用map()方法和对象解构语法提取字段

请求后台接口返回的数据中,很可能会遇到下面这种数据格式:

studentInfo = [
  { name: "Alice", age: 18, no: 2 },
  { name: "Bob", age: 16, no: 5 },
  { name: "Candy", age: 17, no: 3 },
  { name: "Den", age: 18, no: 4 },
  { name: "Eve", age: 16, no: 1 },
]

当我们要获取姓名列表、年龄列表和编号列表的时候,我们可以通过map()再配合对象的解构语法方便快捷地进行处理:

const nameList = studentInfo.map(({ name }) => name)
const ageList = studentInfo.map(({ age }) => age)
const noList = studentInfo.map(({ no }) => no)

// nameList: [ "Alice", "Bob", "Candy", "Den", "Eve" ]
// ageList: [ 18, 16, 17, 18, 16 ]
// noList: [ 2, 5, 3, 4, 1 ]
3、使用filter()方法和对象解构语法过滤数组

接上上面的例子,如果我想获取一个“年龄小于等于17岁”的新列表,应该怎么做呢?类似map()方法,我们可以用filter()方法进行过滤:

const newStudentInfo = studentInfo.filter(({ age }) => {
  return age <= 17
})

/*
newStudentInfo: [
  { name: "Bob", age: 16, no: 5 },
  { name: "Candy", age: 17, no: 3 },
  { name: "Eve", age: 16, no: 1 }
]
*/
4、借助includes()方法求两个数组的差集

假设我们有以下两个数组:

var a = [1, 2, {s:3}, {s:4}, {s:5}]
var b = [{s:2}, {s:3}, {s:4}, "a"]

我们应该如何找到它们的差集呢?传统的方法可能需要把它们以Object形式hash化,但其实我们可以通过.includes()方法更加优雅方便地找出差集,代码如下:

var a = [1, 2, {s:3}, {s:4}, {s:5}].map(item => JSON.stringify(item))
var b = [{s:2}, {s:3}, {s:4}, "a"].map(item => JSON.stringify(item))

var diff = a.concat(b)
            .filter(v => !a.includes(v) || !b.includes(v))
            .map(item => JSON.parse(item))
            
// diff: [1, 2, {s:5}, {s:2}, "a"]

至于为什么要JSON.stringify(),是因为要对比两个“对象元素”是否相等,是无法直接以“对象”形式比较的(永远返回不相等)。

5、后记

本文篇幅较短,难度也相对简单,以上都是一些平时实践中发现的技巧,希望可以对读者们有所启发。如果你也有一些比较优雅好玩的技巧,不妨和我交流分享喔~

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/83697.html

相关文章

  • Vue.js 实践(2):实现多条件筛选、搜索、排序及分页表格功能

    摘要:基础布局的中主要为部分,分别是用于搜索筛选和分页的表单控件用于排序表格的表头以及用于展示数据的。这也是前瞻发布之后,提出废弃部分功能后许多人反应较为强烈的原因。 与上周的第一篇实践教程一样,在这篇文章中,我将继续从一种常见的功能——表格入手,展示Vue.js中的一些优雅特性。同时也将对filter功能与computed属性进行对比,说明各自的适用场景,也为vue2.0版本中即将删除的部...

    Profeel 评论0 收藏0
  • Vue.js 实践(2):实现多条件筛选、搜索、排序及分页表格功能

    摘要:基础布局的中主要为部分,分别是用于搜索筛选和分页的表单控件用于排序表格的表头以及用于展示数据的。这也是前瞻发布之后,提出废弃部分功能后许多人反应较为强烈的原因。 与上周的第一篇实践教程一样,在这篇文章中,我将继续从一种常见的功能——表格入手,展示Vue.js中的一些优雅特性。同时也将对filter功能与computed属性进行对比,说明各自的适用场景,也为vue2.0版本中即将删除的部...

    ChanceWong 评论0 收藏0
  • React项目 - 几种CSS实践

    摘要:一切样式都是全局,产生的各种命名的痛苦,等命名规则能解决一部分问题,但当你使用三方插件时却无法避免命名冲突。这一解决法的优雅在于,全局的可以正常使用,只有带后缀的才会被化使用的模板字符串,在文件里写纯粹的。 前言团队在使用react时,不断探索,使用了很多不同的css实现方式,此篇blog总结了,react项目中常见的几种css解决方案:inline-style/radium/styl...

    princekin 评论0 收藏0
  • css進階

    摘要:栅格系统用于处理页面多终端适配的问题。它表示抓取对象以后拖放到另一个位置。目前,它是标准的一部分。精简高效的命名准则方法这篇文章发布于年月日,星期日,,归类于相关。但是不会受到包含块的限制,可能会溢出。 一劳永逸的搞定 flex 布局 寻根溯源话布局 一切都始于这样一个问题:怎样通过 CSS 简单而优雅的实现水平、垂直同时居中。记得刚开始学习 CSS 的时候,看到 float 属性不由...

    import. 评论0 收藏0
  • [翻译]map和reduce,处理数据结构利器

    摘要:一个简单的实践返回数组或类似结构中满足条件的第一个元素。这个翻译项目才开始,以后会翻译越来越多的作品。 原文地址:https://codeburst.io/writing-javascript-with-map-reduce-980602ff2f2f 作者:Shivek Khurana 简介:本文是一份编写优雅、简洁和函数式ES6代码的快捷清单。 现如今JavaScript有许多问...

    233jl 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<