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

时间:2015-02-13 02:36:40

标签: javascript arrays multidimensional-array

我想将数组'减少'到JavaScript多维数组中每个x(或索引0)值的最大值。

My Array如下:

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中实现这一目标。

修改

Aww男人投了我的问题。

无论如何,这就是我想出来的。

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]]

3 个答案:

答案 0 :(得分:2)

这假设原始数组已经排序。如果没有,您将必须编写附加功能来排序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. 具有相同的值,但比测试对更早出现。这可以防止重复。
    2. 请在此处详细了解使用过的数组方法:filtersome

答案 1 :(得分:1)

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

完全未经测试代码:

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

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

答案 2 :(得分:1)

这是使用地图收集所有唯一值的测试版本,然后输出按月/年排序,并且与输入数据的顺序无关。这也适用于所有浏览器(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;
}