从多维数组中删除重复的元素对

5

我有一个像这样的数组:

1.  coordinates = [ [16.343345, 35.123523],
2.                  [14.325423, 34.632723],
3.                  [15.231512, 35.426914],
4.                  [16.343345, 35.123523],
5.                  [15.231512, 32.426914] ]

第五行的纬度与第三行相同,但经度不同,因此它们不是重复项。

第三行和第六行的纬度和经度都相同,因此它们是重复项,应该删除其中一个。


3
你应该更新你的问题,包括你已经尝试过的任何方法。 - Matt
2
你尝试过对它们进行排序,然后循环遍历结果并比较当前记录和下一个记录吗? - Dave
1
15,231512, 35,426914(4个整数)应该是 15.231512,35.426914(2个浮点数)吗? - Fabrício Matté
对于像从列表中删除重复项这样的任务,你最好使用现有的JS库之一,如[lodash](http://lodash.com/),因为该代码比您编写的任何代码都经过了更多的路试。 - Dancrumb
1
你能否进一步说明你的问题?此外,第6行不存在,并且根据我的计算,第1行和第4行与第3行和第5行相匹配。 - Dancrumb
7个回答

13

这个问题的难点在于,即使两个数组包含相同的值,它们也不会被认为是相等的。因此,直接使用indexOf等比较方法是行不通的。

以下模式可能有用:编写一个将数组转换为标量值并检查这些值在集合中是否唯一的函数(或使用内置函数)。

uniq = function(items, key) {
    var set = {};
    return items.filter(function(item) {
        var k = key ? key.apply(item) : item;
        return k in set ? false : set[k] = true;
    })
}

其中key是将items(无论是什么)转换为可比较标量值的“哈希”函数。 在您的特定示例中,似乎只需对数组应用Array.join即可:

uniqueCoords = uniq(coordinates, [].join)

请注意,在IE < 9中不支持filter - Dancrumb

5
你可以使用标准的javascript函数splice来完成此操作。
for(var i = 0; i < coordinates.length; i++) {
    for(var j = i + 1; j < coordinates.length; ) {
        if(coordinates[i][0] == coordinates[j][0] && coordinates[i][1] == coordinates[j][1])
            // Found the same. Remove it.
            coordinates.splice(j, 1);
        else
            // No match. Go ahead.
            j++;
    }    
}

然而,如果您有成千上万个点,程序会运行缓慢。此时,您需要首先考虑对数值进行排序,然后在一个循环中去重。


1
我重新编写了thg435的答案(他不允许我发表评论),并且还使用jQuery进行了原型编制,因此这将在使用它的所有浏览器上工作(甚至是IE7)。
Array.prototype.uniq = function (key) {
    var set = {};
    return $.grep(this, function (item) {
        var k = key
            ? key.apply(item)
            : item;
        return k in set
            ? false
            : set[k] = true;
    });
}

你可以像这样使用它:
arr = arr.uniq([].join);

1
如果您不使用Safari,这个单行代码就可以完成工作。

var arr = [[16.343345, 35.123523],
           [14.325423, 34.632723],
           [15.231512, 35.426914],
           [16.343345, 35.123523],
           [15.231512, 32.426914]],
    lut = {},
    red = arr.filter(a => lut[a] ? false : lut[a] = true);

document.write("<pre>" + JSON.stringify(red,null,2) + "</pre>");


0

创建另一个只保留唯一坐标对的数组可能会更简单。

var uniqueCoors = [];
var doneCoors = [];
for(var x = 0; x < coordinates.length; x++) {
    var coorStr = coordinates[x].toString();

    if(doneCoors.indexOf(coorStr) != -1) {
        // coordinate already exist, ignore
        continue;
    }

    doneCoors.push(coorStr);
    uniqueCoors.push(coordinates[x]);
}

0
function sortCoordinates(arr){
    var obj = {};
    for(var i = 0, l = arr.length; i < l; i++){
        var el = arr[i];
        var lat = el[0];
        var lng = el[1];

        if(!obj[lat + lng]){
            obj[lat + lng] = [lat, lng];
        } 
    }

    var out = [];
    for(p in obj){
        out.push([obj[p][0], obj[p][1]]);
    }
    return out;
}

-1

我不确定coordinates[][]的数据类型。请相应地进行比较。

  var dubJRows= new Array();
  for(int i = 0; i <  coordinates.length -2; i++){
    for(int j = i+1; j <  coordinates.length -1; j++){
        if (i != j && chk_dubJRows_not_contains(j)) {
           innerArray1 [1][1] = coordinates[i];
           innerArray2 [1][1] = coordinates[j];
           if ( innerArray1 [1][0] == innerArray2[1][0] 
                   && innerArray1[1][1] == innerArray2[1][1]) {
               dubJRows.push(j);
            }
         }
       }
    }
    //REMOVE ALL dubJRows from coordinates.

这是O(n^2)的,根本无法扩展。此外,没有必要从0到coordinates.length扫描j,因为您将重复一些比较。例如,i=3,j=2i=2,j=3是相同的比较。 - Dancrumb
1
OP正在使用JavaScript,而不是Java。 - Dancrumb

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