1

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.

2 Answers 2

2

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);

Sign up to request clarification or add additional context in comments.

1 Comment

concat() works as expected. I was using Set in that way for better representation in my example but thanks for mentioning!
1

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.