根据ES6中的值从数组中删除重复项



我有一个数组,如下所示:

const array = [
{id: 3, amount: 100, productId: 10, title: "Color/Red", variantChildren: Array(0)},
{id: 4, amount: 5, productId: 10, title: "Color/Green", variantChildren: Array(2)},
{amount: 0, variantChildren: {…}, title: "Color/Red"},
{amount: 0, variantChildren: {…}, title: "Color/Green"},
{amount: 0, variantChildren: {…}, title: "Color/Purple"}
]

我需要删除数量为0的重复项。我正试图弄清楚如何使用.filter().forEach()

所以项目[2]&[3]将被移除,并返回一个新的数组:

const newArray = [
{id: 3, amount: 100, productId: 10, title: "Color/Red", variantChildren: Array(0)},
{id: 4, amount: 5, productId: 10, title: "Color/Green", variantChildren: Array(2)},
{amount: 0, variantChildren: {…}, title: "Color/Purple"}
]

将数组缩减为Map,只添加不存在的项、存在的项和存在的项,但总数大于0。

将Map的.values()迭代器转换为具有Array.from()的数组。

const data = [{"id":3,"amount":100,"productId":10,"title":"Color/Red","variantChildren":[]},{"id":4,"amount":5,"productId":10,"title":"Color/Green","variantChildren":[null,null]},{"amount":0,"variantChildren":{},"title":"Color/Red"},{"amount":0,"variantChildren":{},"title":"Color/Green"},{"amount":0,"variantChildren":{},"title":"Color/Purple"}];
const result = Array.from(
data.reduce((acc, o) =>
!acc.has(o.title) || o.amount > 0 ? acc.set(o.title, o) : acc, new Map())
.values()
);
console.log(result);

const data = [
{id: 3, amount: 100, productId: 10, title: "Color/Red", variantChildren: Array(0)},
{id: 4, amount: 5, productId: 10, title: "Color/Green", variantChildren: Array(2)},
{amount: 0, variantChildren:{}, title: "Color/Red"},
{amount: 0, variantChildren: {}, title: "Color/Green"},
{amount: 0, variantChildren: {}, title: "Color/Purple"},
{id: 5, amount: 3, productId: 11, title: "Color/Green", variantChildren: Array(2)},
{id: 6, amount: 10, productId: 12, title: "Color/Red", variantChildren: Array(0)},
{amount: 2, variantChildren: {}, title: "Color/Purple"},
{amount: 0, variantChildren: {}, title: "Color/Purple"},
];
const removeZeroAmountDuplicates = arr => {
// group items by title
const titleItemsMap = arr.reduce((acc,item) => {
const { title, amount } = item;
if(acc[title]) acc[title].push(item);
else acc[title] = [item];
return acc;
}, {});
// iterate over each title's items
const res = Object.values(titleItemsMap).reduce((acc, titleItems) => {
// if list has more than one elements remove zero-amount items, otherwise keep the only element
const items = titleItems.length > 1
? titleItems.filter(item => item.amount !== 0)
: titleItems;
// merge items with acc
return [...acc, ...items]
}, []);
return res;
}
console.log( removeZeroAmountDuplicates(data) );

var unfiltered = [{amount: 0}, {amount: 0}, {amount: 1}, {amount: 2}]
var tmpArray = [];
var filtered = unfiltered.filter((val, index, arr) => {
var tmpTrue = !(tmpArray.map(v => v.amount).includes(val.amount))
tmpArray.push(val)
return tmpTrue;
});
console.log(filtered);

过滤器MDN

那个代码有点不可读。基本上,filter映射通过阵列。提供的函数应返回true或false。如果为true,则将当前值返回到新数组,否则跳过它。我提供的函数映射到临时数组,它会根据每个值进行更新,因为我们需要检查每个元素的amount。因此,映射的数组为每个元素返回amount。使用新数组,我们检查amount是否已经存在,是真是假。

使用.filter.forEach时,必须检查每个元素,如果该元素在较低的索引中找到,则将其删除。

const array = [
{id: 3, amount: 100, productId: 10, title: "Color/Red"},
{id: 4, amount: 5, productId: 10, title: "Color/Green"},
{amount: 0, title: "Color/Red"},
{amount: 0, title: "Color/Green"},
{amount: 0, title: "Color/Purple"}
]
const result = array.filter((el, i) => {
const dupIndex = array.findIndex(e => e.amount === el.amount)
return i <= dupIndex
})
console.log(result)

最新更新