11

I have an array that looks like the following:

array = [[1, 5], [4, 7], [3, 8], [2, 3],  
 [12, 4], [6, 6], [4, 1], [3, 2], 
 [8, 14]]

What I need is the largest number from the first value of the sets, so in this case 12. Looking at some examples online, the best way I saw to accomplish this is :

Math.max.apply Math, array

Problem is, this only works with single dimensional arrays. How would I impliment this for my senario? (jquery allowed)


The end solution:

It wasn't part of the question, but I needed both the min and max from the array, and that changes things a little.

    unless device.IE
        justTheDates    = magnitudeArray.map (i) -> i[0]
        @earliest       = Math.min.apply Math, justTheDates
        @latest         = Math.max.apply Math, justTheDates                 
    else
        @earliest       = magnitudeArray[0][0]
        @latest         = magnitudeArray[0][0]
        for magnitudeItem in magnitudeArray
            @earliest   = magnitudeItem[0] if magnitudeItem[0] < @earliest
            @latest     = magnitudeItem[0] if magnitudeItem[0] > @latest

9 Answers 9

14

You can use .reduce()...

array.reduce(function(max, arr) { 
    return Math.max(max, arr[0]); 
}, -Infinity)

Here's a version that doesn't use Math.max...

array.reduce(function(max, arr) {
    return max >= arr[0] ? max : arr[0];
}, -Infinity);

...and a jsPerf test.

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

9 Comments

+1 For a classic fold example :). A CoffeeScript translation: max = array.reduce ((max, arr) -> Math.max max, arr[0]), -Infinity
I am seeing more votes for this answer. Would someone be interested in making a case for it OVer the one I accepted?
@Fresheyeball: I wouldn't want to say that one is better than the other. A .reduce() just evaluates an Array down to a single value. A .map() is basically a .reduce() that evaluates it down to a new collection. So a .map() behavior can be achieved using .reduce() like this: array.reduce(function(arr, curr) { arr.push(curr[0]); return arr; }, []). And then you'd still use Math.max.apply.... The advantage using the .map() style with .apply is that you avoid the repeated Math.max calls. The advantage of reducing directly to a number is perhaps a little clarity.
Interesting. Yeah I found how the shim works and just implemented a loop for ie8-
@tq: return Math.max.apply(Math, arr.concat(max))
|
9

http://jsfiddle.net/zerkms/HM7es/

var max = Math.max.apply(Math, arr.map(function(i) {
    return i[0];
}));​

So at first you use array.map() to convert the 2-dimensional array to a flat one, and after that use Math.max()

5 Comments

I am not familiar with .map can you explain what is going on there?
@Fresheyeball: developer.mozilla.org/en/JavaScript/Reference/Global_Objects/… --- so it applies a callback to each element. In your case each i is a [1, 5] - array of 2 elements, and you just return first item. After arr.map() is applied you have another array, that contains 1st elements of each nested array
I guess my question is ... is .map more or less efficient than a loop?
@Fresheyeball: I'm sure it is very close to it and I'm also sure it is not a thing you need to think about now. Choose the solution you can read/maintain better
CoffeeScript often suggests node, but it might be worth noting that Array#map isn't supported <= IE8
3

A simple solution using Underscore.js' max that avoids generating an intermediate array:

max = _(array).max(_.first)[0]

(JSFiddle)

2 Comments

I am NOT going to include an entire new lib just do solve this.
OK, then the other solutions will work better :). Underscore has many useful little functions that, in my experience, are used quite often; and it's only 4KB, so, if it is because of library size, you are not in danger of bloating too much when including it.
1

Using a comprehension in CoffeeScript:

Math.max.apply Math, (x[0] for x in array)

Running example

1 Comment

Splats can do the job too: Math.max (x[0] for x in array) ... :)
1

Also, look at _underscore.js. Here is a link to the function _max().

  • It is simply more efficient to read, write and maintain.

The best part about _underscore is that there are about another hundred helper functions similar to _max. Like sort.

Compare the syntax below:

var sortedObject = _.sortBy(object, function(val, key, object) {
    return val;
});

They are easy to chain, and interpret! (Like Douglas Crockford might suggest)

An excellent JSFIDDLE, was provided in this post by @Raynos.

If you are consistently conducting array operations with raw JavaScript, check out _underscore.js, it can greatly simplify your code.

Hope that helps, All the best! Nash

6 Comments

"It is simply more efficient" --- how the library can be more efficient than the underlying language?
Good question, more efficient to write (to read, and maintain). Thanks for the clarification @zerkms. +1. Edited.
I am NOT going to include an entire new lib just do solve this.
Correct. This is for those that are "consistently conducting array operations with raw JavaScript". Some environments are such. If maintaining advanced algorithms this may be an optimization for you. It also comes with a powerful templating engine for advanced data-binding.
Frankly I am not impressed with underscore.
|
1
Array.prototype.maxX = function(){
  return Math.max.apply(Math,this.map(function(o){return o[0];}));
};

Comments

1

I know this is an old post, but if you (or someone else) want the largest number in the whole array, try with:

var array = [[1, 5], [4, 7], [3, 8], [2, 3],  
 [12, 4], [6, 6], [4, 1], [3, 2], 
 [8, 14]];

var max = array.reduce(function (max, arr) {
    return max >= Math.max.apply(max, arr) ? max : Math.max.apply(max, arr);
}, -Infinity);
console.log(max);

In this examlpe, it will return the value 14.

Comments

0

Sample Input: largestOfFour([[4, 5, 1, 3], [13, 27, 18, 26], [32, 35, 37, 39], [1000, 1001, 857, 1]]);

function largestOfFour(arr) {

    var largest = 0;
    var largestArr = [];
    for(var i=0; i<arr.length; i++){
      for(var j=0; j<arr[i].length; j++){

        if(largest < arr[i][j]){
          largest = arr[i][j];
        }
        largestArr[i] = largest;
      }      
      largest = 0;
    }

  return largestArr;
}

You can populate largest numbers into new Array from two dim array.

Comments

0

ES2019 Array.prototype.flat() with destructuring.

const max = Math.max(...arr.flat());

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/flat

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.