我有一个数组,如下所示:
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)