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!

nnnnnn
  • 147,572
  • 30
  • 200
  • 241
simplexity
  • 1,527
  • 1
  • 13
  • 31
  • 4
    `return arr.map(v => Math.max(...v));` – 4castle Oct 11 '17 at 02: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). – nnnnnn Oct 11 '17 at 02:44
  • @4castle so the ... spread syntax essentially expands that sub array out and returns only the maximum value... Intriguing! – simplexity Oct 11 '17 at 02:45
  • @4castle I love your try! Post an answer, we will vote – dhilt Oct 11 '17 at 02:49
  • @4castle Yes, agreed, please post. I'll accept it. – simplexity Oct 11 '17 at 02:53
  • 1
    It looks like Lux came up with it also. You can vote on his :) – 4castle Oct 11 '17 at 02:55
  • https://stackoverflow.com/questions/39342575/max-value-of-a-multidimensional-array-javascript not ES6 but not hard to convert it – epascarello Oct 11 '17 at 02:55
  • The current version of the language specification is [*ECMA-262 ed 8*](http://ecma-international.org/ecma-262/8.0/), aka ECMAScript 2017. [*Edition 6*](http://ecma-international.org/ecma-262/6.0/index.html) (so called ES6) was ECMAScript 2015. ;-) – RobG Oct 11 '17 at 04:11
  • 1
    @simplexity—there is no [*spread operator*](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_operator). ;-) – RobG Oct 11 '17 at 04:16
  • @some—the page is titled "*Spread syntax*". – RobG Oct 11 '17 at 08:57

3 Answers3

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))
}
Lux
  • 17,835
  • 5
  • 43
  • 73
  • 1
    @some—there is no [*spread operator*](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_operator). ;-) – RobG Oct 11 '17 at 04:13
  • You do need a custom sort callback because the default is storing the elements lexicographical: `console.log([10, 9, 20].sort())`. – Felix Kling Oct 11 '17 at 05:31
  • @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*](http://ecma-international.org/ecma-262/8.0/#sec-punctuators) 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". ;-) – RobG Oct 11 '17 at 08:55
2
function largestEach(arr) {
   return arr.map(a => a.reduce((a, b) => Math.max(a, b)));
}
dhilt
  • 18,707
  • 8
  • 70
  • 85
2
function largestEach(arr) {
   return arr.map((a)=> Math.max.apply(null, a))
}
P Ackerman
  • 2,266
  • 20
  • 24
  • This is the fastest solution – Panos Kalatzantonakis Oct 11 '17 at 04:43
  • @PanosK.It might be the fastest, but it will also crash with a stack overflow if the array is large. – some Oct 13 '17 at 01:17
  • @some How large? – P Ackerman Oct 13 '17 at 18:53
  • 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) – some Oct 13 '17 at 22:28