场景问题
假设有这个一个数组,数组不是按顺序排列的,数组的每一项都有一个type字段表示该条数据的类型
-
// type表示类型 // 例如 1代表日任务,2代表周任务,3代表月任务 const orignList = [ { name: "1类型下的任务项...", type: 1 }, { name: "3类型下的任务项...", type: 3 }, { name: "3类型下的任务项...", type: 3 }, { name: "2类型下的任务项...", type: 2 }, { name: "1类型下的任务项...", type: 1 }, { name: "2类型下的任务项...", type: 2 }, { name: "1类型下的任务项...", type: 1 }, { name: "1类型下的任务项...", type: 1 }, { name: "1类型下的任务项...", type: 1 }, { name: "2类型下的任务项...", type: 2 }, { name: "2类型下的任务项...", type: 2 }, { name: "3类型下的任务项...", type: 3 }, { name: "3类型下的任务项...", type: 3 }, { name: "2类型下的任务项...", type: 2 }, { name: "3类型下的任务项...", type: 3 }, ]
现在需要对这些任务进行归类整合,将同一类型的数据整合到一起,并且按type从大到小排序,也就是处理成如下结果
-
当时脑子瓦特了,其实直接使用sort排序就行了,下面强行使用了一堆方法处理,就当一些方法的应用实例了,望周知!!
-
// type表示类型 // 例如 1代表日任务,2代表周任务,3代表月任务 const finalList = [ { "name": "3类型下的任务项...", "type": 3 }, { "name": "3类型下的任务项...", "type": 3 }, { "name": "3类型下的任务项...", "type": 3 }, { "name": "3类型下的任务项...", "type": 3 }, { "name": "3类型下的任务项...", "type": 3 }, { "name": "3类型下的任务项...", "type": 2 }, { "name": "3类型下的任务项...", "type": 2 }, { "name": "3类型下的任务项...", "type": 2 }, { "name": "3类型下的任务项...", "type": 2 }, { "name": "3类型下的任务项...", "type": 2 }, { "name": "3类型下的任务项...", "type": 1 }, { "name": "3类型下的任务项...", "type": 1 }, { "name": "3类型下的任务项...", "type": 1 }, { "name": "3类型下的任务项...", "type": 1 }, { "name": "3类型下的任务项...", "type": 1 }, ]
解决方案
-
先对数据进行按type分类
-
let orignObj = {} // 创建一个空对象 orignList.forEach(item => { if (Object.keys(orignObj).includes(item.type + '')) { // 如果orignObj存在属性名为当前遍历项type的属性,就直接追加数据 // 注意:因为type是数字,但Object.keys得到的数组每一项都是字符串,需要将遍历项的type转换成字符串,否则匹配失败 orignObj[item.type].push(item) } else { // 否则就是第一次添加该属性,做初始操作 orignObj[item.type] = [item] } })
-
最终整理成了如下结构
-
{ "1": [ { "name": "3类型下的任务项...", "type": 1 }, { "name": "3类型下的任务项...", "type": 1 }, { "name": "3类型下的任务项...", "type": 1 }, { "name": "3类型下的任务项...", "type": 1 }, { "name": "3类型下的任务项...", "type": 1 }, ], "2": [ { "name": "3类型下的任务项...", "type": 2 }, { "name": "3类型下的任务项...", "type": 2 }, { "name": "3类型下的任务项...", "type": 2 }, { "name": "3类型下的任务项...", "type": 2 }, { "name": "3类型下的任务项...", "type": 2 }, ], "3": [ { "name": "3类型下的任务项...", "type": 3 }, { "name": "3类型下的任务项...", "type": 3 }, { "name": "3类型下的任务项...", "type": 3 }, { "name": "3类型下的任务项...", "type": 3 }, { "name": "3类型下的任务项...", "type": 3 }, ] }
-
再对数据进行按照属性名降序排序
-
使用了Object.entries方法
-
let temptArr = Object.entries(taskObj) // 转化成数组,数组每一项第一项都是属性名, 第二项是对应的属性值 temptArr.sort((a, b) => b[0] - a[0]) // 按照第一项也就输属性名进行排序
-
得到以下数据
-
[ [ "3", [ { "name": "3类型下的任务项...", "type": 3 }, { "name": "3类型下的任务项...", "type": 3 }, { "name": "3类型下的任务项...", "type": 3 }, { "name": "3类型下的任务项...", "type": 3 }, { "name": "3类型下的任务项...", "type": 3 } ] ], [ "2", [ { "name": "2类型下的任务项...", "type": 2 }, { "name": "2类型下的任务项...", "type": 2 }, { "name": "2类型下的任务项...", "type": 2 }, { "name": "2类型下的任务项...", "type": 2 }, { "name": "2类型下的任务项...", "type": 2 } ] ], [ "1", [ { "name": "1类型下的任务项...", "type": 1 }, { "name": "1类型下的任务项...", "type": 1 }, { "name": "1类型下的任务项...", "type": 1 }, { "name": "1类型下的任务项...", "type": 1 }, { "name": "1类型下的任务项...", "type": 1 } ] ] ]
-
之后遍历该处理的数组得到最后的处理结果
-
let finalArr = temptArr.reduce((prev, curr) => [...prev, ...curr[1]], [])
-
这里本来想着用
Object.fromEntries()
方法去将排序的数据还原回对象的,但还原的数据没有按照属性名进行排序,回到了之前的数据,因此行不通,于是想到了遍历Object.entries()
处理的数组进行解决
用到的方法
Object.keys(obj)
-
参数:要处理的对象
-
返回值:返回该处理对象的属性名数组
-
例如
-
// 对象方法 const a = { name: '小kun', age: 2.5, hobby: ['唱', '跳', 'rap', '篮球'] } const b = [1, 2, 3] const c = '爱你孤身走暗巷' console.log('a.keys', Object.keys(a)) // a.keys (3) ['name', 'age', 'hobby'] console.log('a.values', Object.values(a)) // ["小kun",2.5,["唱","跳","rap","篮球"]] console.log('b.keys', Object.keys(b)) // 返回索引 b.keys (3) ['0', '1', '2'] console.log('b.values', Object.values(b)) // 返回每一项的值 b.values (3) [1, 2, 3] console.log('c.keys', Object.keys(c)) // 返回索引 c.keys (7) ['0', '1', '2', '3', '4', '5', '6'] console.log('c.values', Object.values(c)) // 返回每一项的值 c.values (7) ['爱', '你', '孤', '身', '走', '暗', '巷'] // Object.values(obj) 和Object.keys(obj)类似,参数是处理对象,返回该对象属性值所组成的数组
Object.entries(obj)
-
参数:要处理的对象
-
返回值:处理的对象自身可枚举属性的键值对数组
- 通俗来说就是:返回值是一个数组,数组每一项是一个数组,每一项的第一项是对象的key, 第二项是对象的value
-
例如
-
const a = { name: '小kun', age: 2.5, hobby: ['唱', '跳', 'rap', '篮球'] } const b = [1, 2, 3] const c = '爱你孤身走暗巷' console.log('a.entries', Object.entries(a)) /* [ [ "name", "小kun" ], [ "age", 2.5 ], [ "hobby", [ "唱", "跳", "rap", "篮球" ] ] ] */ console.log('b.entries', Object.entries(b)) /* [ [ "0", 1 ], [ "1", 2 ], [ "2", 3 ] ] */ console.log('c.entries', Object.entries(c)); /* [ [ "0", "爱" ], [ "1", "你" ], [ "2", "孤" ], [ "3", "身" ], [ "4", "走" ], [ "5", "暗" ], [ "6", "巷" ] ] */
Object.fromEntries(obj)
-
和Object.entries(obj)相对应
-
参数:要处理的数组(数组每一项是数组,每一项第一项是属性名,第二项是属性值)
-
返回值:返回一个对象
Array.reduce(fn)
// prev 上一次调用回调时的返回值,或者初始值 init;
// cur 当前处理的数组元素 ,类似于forEach, map之类的item
// index 当前遍历项的索引
// arr 代表arr数组
arr.reduce((prev,cur,index,arr) => {
...
}, init);
1. 求和
let arr = [1, 2, 3, 4]
// 未指定初始值
let sum = arr.reduce((prev, cur) => {
return prev + cur
}) // 10
// 指定了初始值
let sum = arr.reduce((prev, cur) => {
return prev + cur
}, 10) // 20
2.求最大值
let max = arr.reduce(function (prev, cur) {
return Math.max(prev,cur);
}); // 4
3.去重
- 思路
- 初始是空数组
- 遍历每一项
- prev中存在该项就保持prev不变
- 否则就将当前遍历项添加到prev中
- 遍历结束后prev就是最终去重的数组
- 也就是reduce的返回值
const arr1 = [1, 2, 3, 4, 2, 1, 5]
const newArr = arr.reduce((prev, cur) => prev.indexOf(cur) ? [...prev, cur] : prev, [])
console.log(newArr); // [1, 2, 3, 4, 5]
4.数组合并
-
上面用到的就是数组合并的方法
-
初始空数组
-
每遍历一项就将该项数据合并到prev数组中,最终得到合并后的数组
-
let finalArr = temptArr.reduce((prev, curr) => [...prev, ...curr[1]], [])