Reputation: 15166
I like to use Array.prototype.reduce()
for several different scenarios in my code, it's pretty straightforward and handy.
Please observe in the 2 different solutions below the reduce()
function takes 2 different initial values, in the first case is new Set()
and the second is []
.
In the below example the code uses reduce()
without return
keyword - Set
one:
const data = ['a', 'b', 'c', 'd', 'a', 'k', 'b'];
const result = data.reduce((a, c) => a.add(c), new Set());
console.log(Array.from(result));
The next example is using still reduce()
but here with a return
keyword - Array
one:
const data = ['a', 'b', 'c', 'd', 'a', 'k', 'b'];
const result = data.reduce((a, c) => {
a.find(e => e === c) ? null : a.push(c);
return a;
}, []);
console.log(result);
Question:
So the .add()
function for Set
returns the Set
object itself. The .push()
function for Array
returns the length
of the used Array
.
The Set
case helps me to shorten the code using .reduce()
without return
keyword because the above mentioned reason. In my second example I would like to use the solution without return
keyword but still with Array
somehow.
Is there any workaround solution to get the same result but without using return
keyword in the second example? I would like to shorten the code further if possible.
Any help is appreciated.
Upvotes: 1
Views: 947
Reputation: 28994
Array#concat
can add a new item to an array and returns a new array, so can works similar to Set#add
. However, it still needs the conditional operator since you want to either add an element or nothing - for the latter case that's concatenating an array with an empty array:
const data = ['a', 'b', 'c', 'd', 'a', 'k', 'b'];
const result = data.reduce((a, c) => a.concat(a.some(e => e === c) ? [] : c), []);
console.log(result);
Alternatively, you can use spread syntax to again combine two arrays:
const data = ['a', 'b', 'c', 'd', 'a', 'k', 'b'];
const result = data.reduce((a, c) => [...a, ...(a.some(e => e === c) ? [] : c)], []);
console.log(result);
Neither of the two is perfect, to be honest. The existence of the conditional operator makes this harder to read when all one line but it's still an option.
Upvotes: 1
Reputation: 386634
You could take either the accumulator, if found or concat the element to the accumulator.
const data = ['a', 'b', 'c', 'd', 'a', 'k', 'b'];
const result = data.reduce((a, c) => a.find(e => e === c) ? a : a.concat(c), []);
console.log(result);
Just to mention, Set
takes a complete array with the constructor.
const data = ['a', 'b', 'c', 'd', 'a', 'k', 'b'];
const result = Array.from(new Set(data));
console.log(result);
Upvotes: 2