0

我有这个数组,但没有任何保证的顺序

[ [2,1], [2,2], [2,3], [3,1], [3,2], [4,1], [4,2], [4,3], [4,4], [5,1], [5,2] ]

我需要循环遍历它,匹配具有相同 arr[0] 值的那些,然后删除在 arr[1] 处具有最高值的那个。它最终应该看起来像这样:

[ [2,1], [2,2], [3,1], [4,1], [4,2], [4,3], [5,1] ]

我不确定如何准确地迭代这个。大多数地方我都见过过滤复杂对象或从一维数组中删除单个值的方法。

在过去的几天里,我才真正开始使用数组。谢谢您的帮助!

4

3 回答 3

1

好的,我有两个解决方案。 version1是基本的,可以使用一些优化,而version2使用更大、均匀分布的列表应该更快。

如果您只想拥有几件物品,请使用一件。它只有几行代码,所以不会让人分心。如果您有一个大数组并且它会非常均匀地分布,那么使用两个。

我实际上对样本数据进行了测试,并且version2迭代次数少于version1. V1 在外循环中运行了 11 次,在内循环中运行了 79 次。V2 在第一个外循环中运行了 11 次,在第二个外循环中运行了 4 次。第二个循环的内部循环运行了 11 次,而里面的循环只运行了 7 次。所以 v2 的总迭代次数大约是 v1 的 40%。当我将项目加倍时,v2 仅使用 30% 的迭代。

Version2还有其他几个潜在的优势。

  • 我相信Array.push性能成本比Array[index] =. 如果这是真的,那么您知道newAry它将具有原始数组长度的最终长度 -indicies数组长度的长度。因此,您可以使用该长度进行初始化newAry,保留一个计数器变量,然后执行类似newAry[counter++] = someVal.
  • 如果您想保留一个结果(如果只有一个),则进行了一些讨论。如果是这种情况,很容易在第二个循环开始时进行检查:if (iVal.length == 1) // add to newAry else do j,k loops.

版本 1

function version1(ary) {
    var newAry = [];
    var iVal, jVal;
    for (var i = 0, il = ary.length; i < il; i++) {
        iVal = ary[i];
        for (var j = ary.length - 1; j >= 0; j--) {
            if (i != j) {
                jVal = ary[j];

                if (iVal[0] == jVal[0] && iVal[1] < jVal[1]) {
                    newAry.push(iVal);
                    break;
                }
            }
        }
    }

    return newAry;
}

版本 2

function version2(ary) {
    var indices = [];
    var values = [];
    var newAry = [];
    var iVal, 
        index,
        highestFound,
        lowFound;

    for (var i = 0, il = ary.length; i < il; i++) {
        var iVal = ary[i];
        if ((index = indices.indexOf(iVal[0])) == -1) {
            indices.push(iVal[0])
            values.push([ iVal[1] ]);
            index++;
        }
        else {
            values[index].push(iVal[1])
        };
    }

    for (var i = 0, il = values.length; i < il; i++) {
        iVal = values[i];
        highestFound = false;
        for (var j = 0, jl = iVal.length; j < jl; j++) {
            if (!highestFound) {
                lowFound = false;

                for (var k = j + 1, kl = iVal.length; k < kl; k++) {
                    if (iVal[j] < iVal[k]) {
                        lowFound = true;
                        newAry.push([indices[i], iVal[j]]);
                        k = kl;
                    }
                }
                if (!lowFound) {
                    highestFound = true;    
                }
            }
            else {
                newAry.push([indices[i], iVal[j]]);
            }
        }
    }

    return newAry;
}

jsFiddle

带有计数器的 jsFiddle

于 2013-07-10T19:12:19.747 回答
0

根据您到目前为止所提供的内容,这是我提出的代码:

var foo = [
    [2, 1],
    [2, 2],
    [2, 3],
    [3, 1],
    [3, 2],
    [4, 1],
    [4, 2],
    [4, 3],
    [4, 4],
    [5, 1],
    [5, 2]
],
    temp = [];

foo.forEach(function (value, index) {
    if (typeof temp[value[0]] === 'undefined') {
        temp[value[0]] = {
            highestValue: value[1],
            position: index
        };
    } else {
        if (temp[value[0]].highestValue < value[1]) {
            temp[value[0]].highestValue = value[1];
            temp[value[0]].position = index;
        }
    }
});

temp.forEach(function(value, index) {
    delete foo[value.position];
});

请注意,如果您有 infoo例如[6,1],它也会被删除。

于 2013-07-10T19:13:03.783 回答
0

利用优秀的lodash.js库:

var ary = [ [2,1], [2,2], [2,3], [3,1], [3,2], [4,1], [4,2], [4,3], [4,4], [5,1], [5,2] ];

var results = _(ary)

    // Group by the first value
    .groupBy(function(pair) {
        return pair[0];
    })

    // Turn the groups into arrays
    .map(function(group) {

        // Sort by the second value
        var sorted = _.sortBy(group, function(pair) {
                return pair[1];
            });

        // Keep all but the highest value
        return _.take(sorted, sorted.length-1);
    })

    // Remove the groupings
    .flatten(true)

    // Unwrap the results
    .value();

console.log(results);

jsFiddle:http: //jsfiddle.net/dmillz/BhSDT/

我希望这会有所帮助!

于 2013-07-10T19:46:55.147 回答