On the whim of node school, I am trying to use reduce
to count the number of times a string is repeated in an array.
var fruits = ["Apple", "Banana", "Apple", "Durian", "Durian", "Durian"],
obj = {};
fruits.reduce(function(prev, curr, index, arr){
obj[curr] ? obj[curr]++ : obj[curr] = 1;
});
console.log(obj); // {Banana: 1, Apple: 1, Durian: 3}
is sort of working. For some reason, reduce
seems to skip the first element. I don't know why. Its first time through the array, index
is 1
. I tried putting in some logic like, if (index === 1){//put 'prev' as a property of 'obj'}
. But that seems really convoluted. I'm certain that this is not how node school wants me to solve this problem. However, I wonder what's a good way to access the zeroth element in the array you're reducing. Why is this zeroth element seemingly ignored by the reduction procedure? I guess I could pass in fruits[0]
after the callback so I start with that value initially. What's the best way to access this zeroth element?
To count the duplicates in an array: Declare an empty object variable that will store the count for each value. Use the forEach() method to iterate over the array. On each iteration, increment the count for the value by 1 or initialize it to 1 .
To remove duplicates from an array: First, convert an array of duplicates to a Set . The new Set will implicitly remove duplicate elements. Then, convert the set back to an array.
To check how many times an element appears in an array:Declare a count variable and set its value to 0 . Use the forEach() method to iterate over the array. Check if the current element is equal to the specific value. If the condition is met, increment the count by 1 .
The syntax of reduce()
is:
arr.reduce( callback [, initial] );
If you omit initial
value, callback
will get called 5 times, with arr[0]
passed in as the initial value of previous
:
callback( previous=arr[0], current=arr[1], index=0, array=arr );
callback( previous , current=arr[2], index=1, array=arr );
callback( previous , current=arr[3], index=2, array=arr );
callback( previous , current=arr[4], index=3, array=arr );
callback( previous , current=arr[5], index=4, array=arr );
If you include initial
value, callback
will get called 6 times with initial
passed in as the initial value of previous
:
callback( previous=initial, current=arr[0], index=0, array=arr );
callback( previous , current=arr[1], index=1, array=arr );
callback( previous , current=arr[2], index=2, array=arr );
callback( previous , current=arr[3], index=3, array=arr );
callback( previous , current=arr[4], index=4, array=arr );
callback( previous , current=arr[5], index=5, array=arr );
Because you're building an object, I recommend you passed in an empty object { }
as the initial
value:
function reduceFunction(previous, current, index, array) {
// console.log("debug: ", " current: ", current, "index: ", index);
if (!previous[current])
previous[current] = 1;
else
previous[current]++;
return previous;
}
const initial = { };
const fruits = [ "Apple", "Banana", "Apple", "Durian", "Durian", "Durian" ];
const result = fruits.reduce( reduceFunction, initial );
console.log( "result: ", result );
// Output:
//
// result: {
// "Apple": 2,
// "Banana": 1,
// "Durian": 3
// }
Reference:
If no
initialValue
was provided, thenpreviousValue
will be equal to the first value in the array andcurrentValue
will be equal to the second.https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce#Description
Additionally, you have to return a value from the function. That value becomes the value of previousValue
on the next iteration.
I'd suggest you "carry" your aggregator obj
as the initial value.
var fruits = ["Apple", "Banana", "Apple", "Durian", "Durian", "Durian"];
var obj = fruits.reduce(function(carry, fruit){
if(!carry[fruit]) carry[fruit] = 0; // If key doesn't exist, default to 0
carry[fruit]++; // Increment the value of the key
return carry; // Return aggregator for next iteration
}, {});
alert(JSON.stringify(obj));
Here's a simple diagram:
fruit carry (before operation) carry (after operation, returned value)
1st iteration: Apple {} {Apple:1}
2nd iteration: Banana {Apple:1} {Apple:1, Banana:1}
3rd iteration: Apple {Apple:1, Banana:1} {Apple:2, Banana:1}
4th iteration: Durian {Apple:2, Banana:1} {Apple:2, Banana:1, Durian:1}
5th iteration: Durian {Apple:2, Banana:1, Durian:1} {Apple:2, Banana:1, Durian:2}
6th iteration: Durian {Apple:2, Banana:1, Durian:2} {Apple:2, Banana:1, Durian:3}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With