2

Improving my algorithm knowledge using ES6 (I am fairly new to ES6) and wondering if there is any way (if at all performant) of avoiding a for loop in this largest of each array function I wrote?

function largestEach(arr) {
   for(const [i,v] of arr.entries())
      arr[i] = v.sort((a,b) => b - a).filter((e,i) => i === 0);
   return arr.reduce((a,b) => a.concat(b));
}
largestEach([[4, 5, 1, 3], [13, 27, 18, 26], [32, 35, 37, 39], [1000, 1001, 857, 1]]);

Console logs: [5, 27, 39, 1001] which is correct.

It is conceptual so there is no real use case I am using it for. I am not against for loops just curious what my better options were in ES6 (or JS in general). Purely curious!

10
  • 4
    return arr.map(v => Math.max(...v)); Commented Oct 11, 2017 at 2:38
  • I had come up with the same as @4castle. Note that if any of the inner arrays were empty you'd get a result of -Infinity for them, which is better than what the function in the question does in that case (where the output simply skips over any empty arrays, returning an array of different length to the input). Commented Oct 11, 2017 at 2:44
  • @4castle so the ... spread syntax essentially expands that sub array out and returns only the maximum value... Intriguing! Commented Oct 11, 2017 at 2:45
  • 1
    It looks like Lux came up with it also. You can vote on his :) Commented Oct 11, 2017 at 2:55
  • 1
    @simplexity—there is no spread operator. ;-) Commented Oct 11, 2017 at 4:16

3 Answers 3

4

You could simply use .map(). Basically your for loop is equivalent to this:

arr = arr.map(elem => elem.sort((a, b) => b - a).filter(e,i) => i === 0)

However the next thing thats interesting is that you don't have to specify the sort function in this case. Also I wouldn't use .filter(e,i) => i === 0) but rather .pop() or [0].

So you could rewrite:

arr = arr.map(elem => elen.sort()[0])

Next you could use Math.max, so you can rewrite your entire function:

function largestEach(arr) {
  return arr.map(e => Math.max(...e))
}
Sign up to request clarification or add additional context in comments.

3 Comments

@some—there is no spread operator. ;-)
You do need a custom sort callback because the default is storing the elements lexicographical: console.log([10, 9, 20].sort()).
@some—Mozilla does not author the content of MDN, contributors do. Anyone can become a contributor (yes, I'm one but not very active), just create an account and away you go. ... is a punctuator that's used in spread and rest syntax in the same way ; is used to define a statement, but it's not called a "statement operator". ;-)
2
function largestEach(arr) {
   return arr.map(a => a.reduce((a, b) => Math.max(a, b)));
}

Comments

2
function largestEach(arr) {
   return arr.map((a)=> Math.max.apply(null, a))
}

4 Comments

This is the fastest solution
@PanosK.It might be the fastest, but it will also crash with a stack overflow if the array is large.
@some How large?
It depends on the javascript engine, and it can change while the script is running. My limited testing has shown that it is a problem if there are more than 100k items (Chrome 125k, Firefox 500k, Edge 650k). You can easily test it with Math.max.apply(null,Array(900000)). (and change the number)

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.