在Javascript或Coffeescript中获取多维数组中的最大值

11

我有一个类似以下的数组:

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

我需要的是集合中第一个值中最大的数字,因此在这种情况下是12。 通过查看一些在线示例,我发现实现这个目标的最佳方法是:

Math.max.apply Math, array
问题是,这只适用于一维数组。我如何在我的情况下实现这个?(允许使用jquery)
最终解决方案: 这不是问题的一部分,但我需要数组中的最小值和最大值,这会有所改变。
    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个回答

14

你可以使用.reduce()...

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

这是一个不使用Math.max的版本...
array.reduce(function(max, arr) {
    return max >= arr[0] ? max : arr[0];
}, -Infinity);

...以及一个jsPerf测试


3
一个经典的折叠示例:)。一个CoffeeScript的翻译[链接](http://coffeescript.org/#try:array%20%3D%20[[1%2C%205]%2C%20[4%2C%207]%2C%20[3%2C%208]%2C%20[2%2C%203]]%0A%0Amax%20%3D%20array.reduce%20%28%28max%2C%20arr%29%20-%3E%20Math.max%20max%2C%20arr[0]%29%2C%20-Infinity%0Aconsole.log%20max):`max = array.reduce((max, arr) -> Math.max max, arr[0]), -Infinity`。 - epidemian
1
@Fresheyeball: 我不想说哪一种方法更好。一个 .reduce() 只是将一个数组计算为单个值。一个 .map() 基本上是一个 .reduce(),将它计算为一个新的集合。因此,可以使用以下方式通过 .reduce() 实现 .map() 的行为:array.reduce(function(arr, curr) { arr.push(curr[0]); return arr; }, [])。然后仍然会使用 Math.max.apply...。使用 .map() 风格与 .apply 的优点在于避免了重复的 Math.max 调用。直接减少到数字的好处可能是更清晰明了。 - user1106925
1
有趣。是的,我找到了 shim 的工作原理,并为 ie8 实现了一个循环。 - Fresheyeball
能否从“最大”值中获取其他值?例如:如果[8,14]中的8是最高值,我如何得到14 - t q
1
@tq:return Math.max.apply(Math, arr.concat(max)) - user1106925
显示剩余4条评论

9

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

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

首先使用array.map()将二维数组转换为一维数组,然后再使用Math.max()


我不熟悉 .map,你能解释一下那里发生了什么吗? - Fresheyeball
@Fresheyeball: https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/map --- 所以它将回调应用于每个元素。在您的情况下,每个“i”都是一个包含2个元素的[1,5]数组,您只需返回第一个项目。应用了arr.map()之后,您将获得另一个数组,其中包含每个嵌套数组的第一个元素。 - zerkms
我猜我的问题是 ... .map比循环更高效还是不如循环? - Fresheyeball
1
@Fresheyeball:我相信它非常接近,而且我也相信现在不是你需要考虑的事情。选择你能够更好地阅读/维护的解决方案。 - zerkms
CoffeeScript通常建议使用node,但值得注意的是Array#map不支持<= IE8。 - numbers1311407
非常好的使用.map()!谢谢,先生! - Dom

3

使用Underscore.js的 max 可以避免生成一个中间数组的简单解决方案:

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

(JSFiddle)

的翻译是:

(JSFiddle)


我不会为了解决这个问题而包含整个新库。 - Fresheyeball
1
好的,那么其他解决方案会更好 :). Underscore有许多有用的小函数,在我的经验中经常被使用; 而且它只有4KB,所以如果是因为库大小,当包含它时你不需要担心会膨胀太多。 - epidemian

1
在CoffeeScript中使用理解(comprehension):
Math.max.apply Math, (x[0] for x in array)

运行示例


1
星号参数(Splats)也可以胜任Math.max (x [0] for x in array) ... :) - epidemian

1

此外,请看_underscore.js。这里是_max()函数的链接。

  • 使用_underscore更高效,更易读、写和维护。

_underscore最好的部分是还有大约一百个类似于_max的辅助函数,例如sort。

请比较下面的语法:

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

它们易于链接和解释! (就像Douglas Crockford可能建议的那样)

这篇@Raynos的帖子中提供了一个优秀的JSFIDDLE

如果您一直在使用原始JavaScript进行数组操作,请查看_underscore.js,它可以极大地简化您的代码。

希望能有所帮助, 祝一切顺利! Nash


1
它只是更有效率 --- 图书馆如何比底层语言更有效率? - zerkms
好问题,更高效地编写(阅读和维护)。感谢@zerkms的澄清。+1。已编辑。 - Nash Worth
1
我不会为了解决这个问题而包含整个新库。 - Fresheyeball
正确。这是针对那些“一直使用原始JavaScript进行数组操作”的人。有些环境就是这样。如果要维护高级算法,这可能是一种优化方法。它还配备了一个强大的模板引擎,用于高级数据绑定。 - Nash Worth
坦白说,我对下划线并不感到印象深刻。 - Fresheyeball
你能告诉我们它的缺点或不足吗?由于有这么多.js库,一个好的或坏的库通常取决于上下文和环境的最佳匹配。希望这可以帮到你。祝一切顺利!纳什(感谢您的评估)。 - Nash Worth

1
Array.prototype.maxX = function(){
  return Math.max.apply(Math,this.map(function(o){return o[0];}));
};

1

我知道这是一个旧帖子,但如果你(或其他人)想要整个数组中最大的数字,请尝试使用以下方法:

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);

在这个例子中,它将返回值14。

0

示例输入: 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;
}

你可以从二维数组中将最大的数字填充到新数组中。


0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接