# 数组的数据处理
# 数组一些重要的方法
// 将伪数组转换为数组,比如装换arguments
Array.prototype.slice.call(arguments)
// 取arguments的第2~n-1项
Array.prototype.slice.call(arguments, 1, -1)
function getParams() {
console.log(Array.prototype.slice.call(arguments))
console.log(Array.prototype.slice.call(arguments, 1, -1))
}
getParams(1, 3, 5) // [1,3,5] [3]
// 改变原数组,并返回被删除的值
// 比如下面操作只剩下数组第二项,1是开始位置,2是截取长度
Array.prototype.splice.call([12, 13, 14], 1, 2) // [13,14]
// 1位置开始删除两个元素,并插入一个'ccc'。返回的是被删除的两个元素
Array.prototype.splice.call([12, 13, 14], 1, 2, 'ccc')
function spliceParams() {
// 从下表1开始删除两个元素,并插入一个元素'ccc'
Array.prototype.splice.call(arguments, 1, 2, 'ccc')
console.log(Array.prototype.slice.call(arguments))
}
spliceParams(1, 2, 3) // [1, 'ccc']
# 一维数组去重
const arr = [1, 3, 5, 5, 5, 5]
const distinct = (arr) => {
return [...new Set(arr)] // new Set() 返回一个可迭代对象,将其转换成数组
}
distinct(arr) // [1,3,5]
# 数组元素为对象的去重
function distinct(arr, key) {
const map = new Map()
return arr.filter((item) => !map.has(item[key]) && map.set(item[key], null)) // 检测map中没有[key],有则返回false,无则向Map中设置值
}
const list = [
{
name: 'xbl',
age: 15,
},
{
name: 'xbl',
age: 25,
},
{
name: 'cc',
age: 13,
},
]
distinct(list, 'name')
# 二维数组转一维数组,从数组里取对象并合并对象成数组
// 数据格式
const arrList = [
[
(type: 'home'),
(news: [
{
name: 'home1',
content: 'home111',
},
{
name: 'home2',
content: 'home222',
}
]),
],
[
(type: 'user'),
(news: [
{
name: 'user1',
content: 'user111',
},
{
name: 'user2',
content: 'user222',
}
]),
],
[
(type: 'friends'),
(news: [
{
name: 'friends1',
content: 'friends111',
}
]),
],
]
如上所示,是一个二维数据,我们想分别取出数组的第一项和剩余的项,
const [arr1, ...arr2] = arrList
现在 arr1 和 arr2 都是一维数组了,我们想把 arr 数组里面每一项的 news 对象数据,把他们合并为一个数组
const newsList = news.reduce((prev, item) => {
return [...prev, ...item.News]
}, [])
reduce 第二个参数必须要给,否则由于第一个 prev 不是可迭代的而报错(因为第一个是{type: ....,}这种形式的对象,不可迭代,不可使用...展开运算符)
# 树结构数据进行递归处理
// 如下字段
const data = [
{
Name: '买房',
ID: '123',
Items: [
{
ID: '123123',
Name: '新房',
},
{
ID: '123456',
Name: '买房风险',
},
],
},
{
Name: '卖房',
ID: '456',
Items: [
{
ID: '123167',
Name: '卖旧买新',
},
{
ID: '126890',
Name: '卖房流程',
},
],
},
]
为了使数据能够适配,ant-mobile 的多级选择,现在的需求是把字段 ID 变为 value, Name 改为 value, Items 改成 children
const filterData = (data) => {
return data.map((item) => {
const { Name, ID, Items = [] } = item
return {
label: Name,
value: ID,
children: Items && Items.length > 0 ? filterData(Items) : Items,
}
})
}
# 树结构数据进行遍历查找
在省市区选择的时候,根据已选择的 ID 进行查找对应的节点
比如现在有这么个数据结构
const example = [
{
value: 1,
label: '河北省',
children: [
{
value: 11,
label: '保定市',
children: [
{
value: 111,
label: '满城区',
children: [],
},
],
},
{
value: 12,
label: '石家庄市',
children: [],
},
],
},
]
现在已知用户选择的是[1,11,111],如何输出['河北省','保定市','满城区']
let res = []
;[1, 11, 111].reduce((prev, current) => {
const c = prev.find((v) => v.value === current)
res.push(c.label)
return c.children
}, example)
# Array 原型对象上的遍历方法
- for-in, 使用
break
可以终止循环,(只能跳出一层),使用continue
可以跳出本次循环 - for-of, 可以终止/跳出循环,
打断循环,在 h5 使用rc-form
获取错误信息的时候用到了(如果是数组的话,建议用 find,filter 等实现)。比如:
let info = {
xblcity: {
age: 17,
message: '年龄过小',
},
xbl: {
age: 37,
message: '年龄过大',
},
}
// 现在我们想获取info的第一个对象的message
let message
for (let i = 0; i < Object.keys(info).length; i++) {
let findObj = info[Object.keys(info)[i]]
message = findObj.message
break
}
console.log(message) // 年龄过小
接着上述的例子,由于对象没有自带的迭代器,我们无法通过for(item of info) {console.log(item)}
对其进行遍历,可以给该对象定义Symbol.iterator
属性,使用for-of
的时候会调用该方法
let info = {
xblcity: {
age: 17,
message: '年龄过小',
},
xbl: {
age: 37,
message: '年龄过大',
},
}
info[Symbol.iterator]
- forEach arr.forEach(callback(currentValue [, index [, array]])[, thisArg])
不支持链式操作(因为没有返回值), 不能跳出循环,可以在迭代中使用arr[index] = xxx
进行改变数组的操作
# 参数均为函数,且函数都有三个可选参数,第一个是项,第二个是下标,第三个是数组本身。
- every 数组的每一次循环都返回 true,则返回 true
- some 有一项循环返回 true,则返回 true,对性能比较友好
- find 返回符合的 第一个项, 否则返回 undefined
- findIndex 返回符合的项的下标
- indexOf 返回符合项的下标,与 findIndex 类似,用于一元简单数组
- filter 返回符合条件的数组
- map "map"即"映射",也就是原数组被"映射"成对应新数组。 返回 数组每一项 的 全新值,每一次遍历都要有 return 值,否则返回值是 undefined
let arr = [1, 2, 3]
arr = arr.map((item) => {
return item * 2
})
# sort() 对数组进行排序 会改变原数组
const arr = [
{
name: 'xbl',
age: 17,
},
{
name: 'city',
age: 20,
},
{
name: 'xblcity',
age: 18,
},
]
// 从大到小进行排序
let newArr = arr.sort((current, next) => {
if (current.age < next.age) {
// 前面的值 小于 后面的值, 交换顺序
return 1 // 返回true, next在前,current在后
} else if (current.age > next.age) {
return -1 // 返回false, current在前,next在后
} else {
return 0 // 保持原来的顺序
}
})
// 简洁写法
let anotherNewArr = arr.sort((current, next) => {
return next.age - current.age // 小的在前,交换顺序
})
console.log(newArr)
console.log(anotherNewArr)
console.log(arr)
# reduce() 对数组进行计算
参数有两个,第一个是函数,函数有四个可选参数,上一次返回值,项,下标,原数组。 第二个参数用于第一次计算的返回值
const arr = [1, 2, 3, 4, 5]
arr.reduce((prev, item) => {
return prev + item
}, 0)
← 数据结构与算法 lodash omit →