Reputation: 952
I have a function which count the total of the cart and the quantity of items inside it, the function is called every time an item has changed or a new one has been added.
I was looking for the best way to achieve the counting of total and quantity in one function, for now the function looks like this:
cartTotal(): void{
this.carrello.totale = this.carrello.plu.reduce((total, item) => {
return total + (item.prezzo * item.qta);
}, 0);
const count = this.carrello.plu.reduce((qta, item) => {
return qta + (item.qta);
}, 0);
this.cartCount.next(count);
}
But i would reduce the function to only one .reduce
so i've tryed the following solution:
cartTotal(): void{
let count = 0;
this.carrello.totale = this.carrello.plu.reduce((total, item) => {
count += item.qta;
return total + (item.prezzo * item.qta);
}, 0);
this.cartCount.next(count);
}
But the last one does not convince me, so i was wondering which would be the best solution to it..
Upvotes: 3
Views: 10409
Reputation: 1
Here's a cool way to return two values using reduce()
. This function uses reduce()
to return one array with two calculated values. The first value is the sum of all of the odd elements in the passed-in array, and the second value is the sum of all of the even elements.
alternatingSums = array => array.reduce((accumulator,value,i) => {
// if the index of the passed-in array is odd then add the value to the
// the first element of the accumulator array
// otherwise add it to the second element of the array
accumulator[i%2]+=value;
return accumulator}, [0,0])
alternatingSums([20, 10, 30, 15, 5]) // =>[ 55, 25 ]
It's technically one value because it's one array, but you're getting two values in that one array.
Upvotes: 0
Reputation: 369468
You cannot return two values in reduce
. Period. In fact, this has nothing to do with reduce
. You cannot return two values at all in ECMAScript (or TypeScript).
There are languages with multiple return values (Go, for example) but ECMAScript / TypeScript is not one of those languages.
However, ECMAScript does have multiple ways of bundling multiple values into one value: collections (arrays, maps, sets) and objects.
So, while you cannot return two values, you can return a collection (or an object) with two values. In most languages, you would probably return a two-element array (or a tuple in TypeScript), but ECMAScript has very lightweight object literals, so let's use that:
cartTotal(): void {
const { quantity, total } = this.carrello.plu.reduce(
({ quantity, total }, { qta, prezzo }) =>
({ quantity: quantity + qta, total: total + prezzo * qta }),
{ quantity: 0, total: 0 }
);
this.carrello.totale = total;
this.cartCount.next(quantity);
}
The explanations for reduce
are often misleading. reduce
is generally explained as "you reduce the collection down to a single value", but you should never forget that the "single value" can still be as complex as you like! It can still be an array, or an object, or an array-of-arrays-of-objects-of-promises, or …
In fact, if you look at the Wikipedia page for Fold, you will find at the bottom of the page a proof that Fold (which is just the more common name for reduce
) is universal, by which is meant that every iteration over a collection can be written as reduce
.
Upvotes: 1
Reputation: 55443
You can use .reduce
in following way,
cartTotal(): void{
const {total, quantity} = this.carrello.plu.reduce((acc, item) => { // const{total, quanity} this is Destructuring assignment
acc.quantity += item.qta;
acc.total = acc.total + (item.prezzo * item.qta);
return acc;
}, {total:0, quantity:0});
this.cartCount.next(acc.quantity); // emit whatever you want to emit.
}
console.log('Total Price', total, 'Total Quantity', quantity);
// ********************** EXAMPLE ************************************
const {total, quantity} = [{qta:5, prezzo: 100}, {qta:5, prezzo: 100}, {qta:5, prezzo: 100}]
.reduce((acc, result) => {
acc.quantity += result.qta;
acc.total = acc.total + (result.prezzo * result.qta);
return acc;
}, {total:0, quantity:0});
console.log('Total Price', total, 'Total Quantity', quantity);
Upvotes: 6