I suffer for a long time and do not understand how to filter such an array using the title and size
const items = [
{title: 'pepperoni', size: 0, count: 1}
{title: 'pepperoni', size: 1, count: 3}
{title: 'pepperoni', size: 2, count: 1}
{title: 'cheese', size: 0, count: 2}
]
Desired result has unique titles, summed counts and 0 size...
[
{title: 'pepperoni', size: 0, count: 5}
{title: 'cheese', size: 0, count: 0}
] // result that i need
I tried this:
items.filter(obj => obj.title === 'pepperoni' && obj.size === 0) // my last try
I will be very grateful for your help!
CodePudding user response:
reduce()
invokes its block parameter for every element in the array, also passing the result of the prior iteration.
A common use of this is to reduce an array to one that contains unique elements, where uniqueness is determined by the block.
const items = [
{title: 'pepperoni', size: 0, count: 1}
{title: 'pepperoni', size: 1, count: 3}
{title: 'pepperoni', size: 2, count: 1}
{title: 'cheese', size: 0, count: 2}
];
// create an object whose keys are items' titles and values
// include the total count for each
const itemsByTitle = items.reduce((acc, item) => {
let title = item.title; // by making it a key on acc, title will be unique
// if it's not a key, make title a key, beginning with 0 count
if (!acc[title]) acc[title] = { title, count: 0 };
// increment the count for the title by the element's count
acc[title].count = item.count; // for each matching title, add its count
return acc; // return it, because this is passed to the next iteration
},{} /* see note */);
// note: since there's no "prior iteration" on the first iteration,
// this param tells reduce what to pass to begin
Now itemsByTitle
will look like this:
{
pepperoni: { title:'pepperoni', count: 5 },
cheese: { title:'cheese', count: 2 }
}
and the OP's desired output will be given by Object.values(itemsByTitle)
Demo
const items = [
{title: 'pepperoni', size: 0, count: 1},
{title: 'pepperoni', size: 1, count: 3},
{title: 'pepperoni', size: 2, count: 1},
{title: 'cheese', size: 0, count: 2}
];
const itemsByTitle = items.reduce((acc, item) => {
let title = item.title;
if (!acc[title]) acc[title] = { title, count: 0 };
acc[title].count = item.count;
return acc;
},{});
console.log(Object.values(itemsByTitle))
CodePudding user response:
You are unclear about what do you want your items to be filtered by. The only common thing I can see in the items within your "result" array is that both items have a size of 0 so I assume that's what you are trying to filter by which is quite simple:
const result = items.filter((item) => item.size === 0)