在JavaScript多维数组中查找每个x值的最大值

Find Max value of each x value in JavaScript multidimensional array

本文关键字:最大值 查找 JavaScript 数组      更新时间:2023-11-03

对于JavaScript多维数组中的每个x(或索引0)值,我想将数组"减少"为仅最大值。

我的阵列如下:

var mulitple = [["1/2013", 1],
                ["1/2013", 5],
                ["1/2013", 7],
                ["1/2013", 6],
                ["1/2013", 5],
                ["2/2013", 7],
                ["2/2013", 10],
                ["2/2013", 10],
                ["3/2013", 7],
                ["3/2013", 10],
                ["3/2013", 10],
                ["4/2013", 1],
                ["4/2013", 5],
                ["4/2013", 7],
                ["4/2013", 6],
                ["4/2013", 5],
                ["5/2013", 7]];

因此,最终结果应该如下:

[["1/2013", 7],
 ["2/2013", 10],
 ["3/2013", 10],
 ["4/2013", 7],
 ["5/2013", 7]];

我如何在JavaScript中实现这一点。

编辑:

投票否决了我的问题的人。

不管怎样,这就是我想到的。

var max = 0;
var newarray = [];
for (var i = 1; i < mulitple.length; i++) {
    if (mulitple[i - 1][0] == mulitple[i][0]) {
        if (mulitple[i - 1][1] > max) {
            max = mulitple[i - 1][1];
        }
    }
    else {
        if (mulitple[i - 1][1] > max) {
            max = mulitple[i - 1][1];
        }
        newarray.push([mulitple[i - 1][0], max]);
        max = 0;
    }
}
newarray.push([mulitple[mulitple.length - 1][0], max]);

我遇到的问题是,我无法获得数组中的最后一个值(对于唯一的记录)。这是我运行上述代码后得到的结果。

[["1/2013", 7], ["2/2013", 10], ["3/2013", 10], ["4/2013", 7], ["5/2013", 0]]

这假设原始数组已经排序。如果没有,您将不得不编写额外的函数来对out进行排序。

function findMaximums(data) {
    var out = [], maximums = {}, order = new Set;
    data.reduce(function(acc, pair) {
        if (
            // Accumulator has value and it's lower than current
            (acc[pair[0]] && acc[pair[0]][1] < pair[1]) ||
            // Accumulator doesn't have value
            !acc[pair[0]]
        ) {
            acc[pair[0]] = pair; // Store maximum in accumulator
            order.add(pair[0]) // Store order in set
        }
        return acc;
    }, maximums);
    order.forEach(function(key) {
        out.push(maximums[key]); // Populate out with maximums by order
    });
    return out;
}
findMaximums(multiple);
/*[
    [
        "1/2013",
        7
    ],
    [
        "2/2013",
        10
    ],
    [
        "3/2013",
        10
    ],
    [
        "4/2013",
        7
    ],
    [
        "5/2013",
        7
    ]
]*/

更新1:相同,但没有Set

function findMaximums(data) {
    var order = [];
    var maximums = data.reduce(function(acc, pair) {
        if (
            // Accumulator has value and it's lower than current
            (acc[pair[0]] && acc[pair[0]][2] < pair[1]) ||
            // Accumulator doesn't have value
            !acc[pair[0]]
        ) {
            // Store maximum
            acc[pair[0]] = pair;
            // Store order
            if (order.indexOf(pair[0]) === -1) {
                order.push(pair[0])
            }
        }
        return acc;
    }, {});
    return order.map(function(key) {
        return maximums[key]; // Populate out with maximums by order
    });
}

更新2:较短版本。

function findMaximums(data) {
  return data.filter(function(p1, i1) {
    return !data.some(function(p2, i2) {
      return p1[0] === p2[0] && ( (p1[1] < p2[1]) || (p1[1] === p2[1] && i1 > i2) );
    });
  });
}

在这个版本中,如果输入数据中没有其他对,我让对保持在输出中:

  1. 同月
  2. 有更大的价值

  1. 具有相同的值,但发生时间早于测试对。这样可以防止重复

在这里阅读更多关于使用的数组方法:filter,some。

假设数组是在原始问题中定义的,它被排序为将每个分组放在一起。。。

完全未经测试代码:

var reduced = [];
var groupName = '';
var groupMax;
var groupIndex;
var l = multiple.length; // Grab the array length only once
for (var i = 0; i < l; i++){
    // Current Group Name doesn't match last Group Name
    if (multiple[i][0] !== groupName) {
        // Last Group Name is not empty (it's not the first Group)
        if (groupName !== '') {
            // Assume groupIndex has been set and grab the item
            reduced.push(multiple[groupIndex]);
        }
        // Grab the new Group Name and set the initial Max and Index
        groupName = multiple[i][0];
        groupMax = multiple[i][1];
        groupIndex = i;
    }
    // Current Value is bigger than last captured Group Max
    if (multiple[i][1] > groupMax) {
        // Grab the new Group Max and the current Index
        groupMax = multiple[i][1];
        groupIndex = i;
    }
}
// Grab the last index, since there's no new group after the last item
reduced.push(multiple[groupIndex]);

可能存在一些语法或逻辑错误。我实际上并没有运行这个代码,但我认为这个概念是正确的。

这是一个测试版本,使用映射来收集所有唯一值,然后输出按月/年排序,与输入数据的顺序无关。这也适用于所有浏览器(IE6+)。

工作演示:http://jsfiddle.net/jfriend00/dk1tc73s/

function findLargest(list) {
    var map = {}, output = [], item, key, val, current;
    for (var i = 0; i < list.length; i++) {
        item = list[i];
        key = item[0];
        val = item[1];
        current = map[key];
        if (current) {
            // this date is in the map, so make sure to save the largest
            // value for this date
            if (val > current) {
                map[key] = val;
            }            
        } else {
            // this date is not yet in the map, so add it
             map[key] = val;
        }
    }
    // map contains all the largest values, output it to an array
    // the map is not in a guaranteed order
    for (var key in map) {
        output.push([key, map[key]])
    }
    // actually parse to numbers in sort so the comparison
    // works properly on number strings of different lengths
    function parseDate(str) {
        var split = str.split("/");
        return {m: +split[0], y: +split[1]};
    }
    // now sort the output
    output.sort(function(t1, t2) {
        var diffYear, a, b;
        a = parseDate(t1[0]);
        b = parseDate(t2[0]);
        diffYear = a.y - b.y;
        if (diffYear !== 0) {
            return diffYear;
        } else {
            return a.m - b.m;
        }
    });
    return output;
}