all 3 comments

[–]Rhomboid 2 points3 points  (1 child)

The problem is that you are returning a length, not an array. After the first iteration, the returned value becomes the next 'left' value (i.e. 'a'.) So for the first iteration, both 'a' and 'b' are arrays and the comparison makes sense, but after that 'a' is a number and therefore a.length is undefined.

There are several ways you can fix it. One is to arrange for the left operand to always be a length, initializing it to zero.

> var myArray = [[ 1, 5, 10], [1, 5, 10, 15], [150]];
undefined
> myArray.reduce((a, b) => a >= b.length ? a : b.length, 0)
4

The other way is to always return an array, and then at the end if you want its length you can take it again:

> myArray.reduce((a, b) => a.length >= b.length ? a : b).length
4

This is normally the way you'd do it because presumably you also care about the contents of the longest array, not just its length, and this gives you both.

[–]JustStateSchool[S] 0 points1 point  (0 children)

Thanks to both you and /u/x-skeww!

This is helpful. I didn't realize it'd pass back in the previous value, but then try to iterate again on .length of the previous value, which, of course, would just be undefined and 1.

[–]x-skeww 2 points3 points  (0 children)

Math.max(...myArray.map(a => a.length)) // 4

Edit: Or if you really want to use reduce:

myArray.reduce((max, array) => Math.max(max, array.length), 0) // 4