知识点补充1:使用 Set 数据结构实现并集、交集和差集。
var set1 = new Set([1,2,3]);
var set2 = new Set([2,3,4]);
// 并集
let union = new Set([...set1, ...set2]); // {1, 2, 3, 4}
// 交集
let intersect = new Set([...set1].filter( x => set2.has(x))); // {2, 3}
// 差集
let difference = new Set([...set1].filter(x => !set2.has(x))); // {1}
// 实战
function intersection (data, origin, key) {
return [...new Set(data.map(item => item[key]))].filter(
x => new Set(origin).has(x)
)
}
const tabData = [
{ key: 'changeList', name: '货权转移', componentName: 'goods-change' },
{ key: 'adjustList', name: '库存调整', componentName: 'adjust-list' },
{ key: 'freezeList', name: '库存冻结', componentName: 'stock-freeze' },
]
const origin = ['changeList']
console.log(intersection(tabData, origin, 'key')) // changeList
知识点补充2:reduce 函数的返回值分配给累计器,该返回值在数组的每个迭代中被记住,并最后成为最终的单个结果值。
const array1 = [1, 2, 3, 4];
array1.reduce((accumulator, currentValue) => accumulator + currentValue, 0) // 10
reduce 函数实现数组并集、交集。
const arr1 = [{ name: 'zhangsan', age: 20 }, { name: 'lisi', age: 18 }, { name: 'wangwu', age: 17 }]
const arr2 = [{ name: 'maliu', age: 19 }, { name: 'lisi', age: 18 }, { name: 'wangwu', age: 17 }]
// 并集
let obj = []
let result = [...arr1, ...arr2].reduce(function (prev, cur) {
obj[cur.name] ? '' : obj[cur.name] = true && prev.push(cur)
return prev
}, [])
console.log(result)
// [{ name: 'zhangsan', age: 20 }, { name: 'lisi', age: 18 },
// { name: 'wangwu', age: 17 },{ name: 'maliu', age: 19 }]
// 定义一个取交集的函数
function intersection(prev, next, key) {
let arr = prev.map(item => item[key])
return next.filter(item => {
return new Set(arr).has(item[key])
})
}
let getNewArr = [arr1, arr2].reduce((prev, next)=>{
return intersection(prev, next, 'name')
})
console.log(getNewArr)
// [{ name: 'lisi', age: 18 }, { name: 'wangwu', age: 17 }]
进阶:上述案例中,我们都是用的单一条件去重处理的,如何使用多条件处理呢?
function process(arr) {
// 缓存用于记录
const cache = [];
for (const t of arr) {
// 检查缓存中是否已经存在
if (cache.find(c => c.name === t.name && c.age === t.age)) {
// 已经存在说明以前记录过,直接忽略
continue;
}
// 不存在就说明以前没遇到过,把它记录下来
cache.push(t);
}
// 记录结果就是过滤后的结果
return cache;
}
实战:使用 reduce 来判断是否有交集。
针对勾选是否有重复数据. globalInvId 为数据的唯一标识, 使用 globalInvId 来判断是否已勾选改数据.
// 已添加数据
const arr = this.tableData.reduce((prev, next) => {
prev.push(next.globalInvId)
return prev
}, [])
// 所选数据
const brr = data.reduce((prev, next) => {
if (arr.includes(next.globalInvId)) {
prev.push(next)
return prev
}
return prev
}, [])
// 获取重复数据
if (brr.length) {
this.$error({
title: '所选商品与已添加商品重复',
content: <div>
{
brr.map(item => {
return <p>第{item.lineNo}行商品已经添加</p>
})
}
</div>,
})
} else {
.....
}