4

I have two arrays [a,b,c,d] and [b,d,f,h].

I want to get an array back with the common elements [b,d].

I can achieve that with a combination of filter and indexOf:

[a,b,c,d].filter(el => [b,d,f,h].indexOf(el) !== -1)

but I was wondering if and how I can do the same with reduce.

I admit that, despite looking at many examples, reduce still is to me one of the most obscure JS methods, so I'd really appreciate some advice.

1
  • Try to implement filter using reduce Commented Jun 2, 2016 at 15:27

3 Answers 3

6

ES6, a propoosal with Array#includes

The includes() method determines whether an array includes a certain element, returning true or false as appropriate.

On every loop of aa, reduce adds the element to the result array if the value is found in the test array bb. If not found, the former result is returned.

var aa = ['a','b','c','d'],
    bb = ['b','d','f','h'],
    cc = aa.reduce((r, a) => bb.includes(a) && r.concat(a) || r, []);

console.log(cc);

Just a smarter approach with using a single array which contains all arrays.

var aa = ['a','b','c','d'],
    bb = ['b','d','f','h'],
    result = [aa, bb].reduce((a, b) => a.filter(c => b.includes(c)));

console.log(result);

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

8 Comments

I like that a lot, thanks! Do you know a way of using reduce only to achieve the same result?
you mean without includes or indexof?
Yes, which is probably down to me not understanding reduce.
Good answer Nina! I didn't know exactly the behaviour of your code, so I did a fiddle to better understand for me your code. Probably it would help someone :-) jsfiddle.net/joherro3/c69vgzL4/2
@JoseHermosillaRodrigo, right its the short form of if... or better a ternary.
|
2

Reduce is designed to return a single value from a list of items. So filter makes much more sense here.

A good use for reduce would be to return the total number of common elements. Check it out here: https://jsfiddle.net/c69vgzL4/

var a = ['a','b','c','d']
var b = ['b','d','f','h']

var number_of_common = b.reduce(function(prev, next) {
    return prev + (a.indexOf(next) + 1 ? 1 : 0)
}, 0)

$('body').html(number_of_common)

Comments

1

Not only two arrays but for an intersection of n arrays... Let's invent Array.prototype.intersect()

Array.prototype.intersect = function(...a) {
  return [this,...a].reduce((p,c) => p.filter(e => c.includes(e)));
}

var arrs = [[0,2,4,6,8],[4,5,6,7],[4,6]],
     arr = [0,1,2,3,4,5,6,7,8,9];

console.log(JSON.stringify(arr.intersect(...arrs)));

// or just do

console.log(JSON.stringify(["a","b","c","d"].intersect(["b","d","f","h"])));

2 Comments

Do you need JSON.stringfy?
@U r s u s Actually no but it shows the arrays and objects horizontally.

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.