用于返回2D数组中的不同值的函数

时间:2012-01-27 15:38:41

标签: javascript

我有以下2D数组

var items = [['al','bv','sd'],
             ['al','cc','ab'],
             ['cv','vv','sw'],
             ['al','bv','sd']
            ];

我需要一个函数,它会返回一个类似的数组,但具有不同的值。例如,在上面的数组中,['al','bv','sd']发生了两次。

我希望函数能够返回我:

var items = [['al','bv','sd'],
             ['al','cc','ab'],
             ['cv','vv','sw']
            ];

8 个答案:

答案 0 :(得分:6)

快速而肮脏的解决方案,假设数据很小。

在每次迭代中,将行转换为字符串。如果字符串尚未存在于地图中,请使用字典存储值为True的字符串。另外,将它添加到输出数组。如果它已经在字典中,请转到下一个项目。

示例:

var d = {};
var out = [];
for( var i = 0; i < items.length; i++ ) {
    var item = items[i];
    var rep = item.toString();

    if (!d[rep]) {
        d[rep] = true;
        out.push(item);
    }
}

// out has the result

答案 1 :(得分:3)

你必须循环两次(或三次):

  1. 从头到尾遍历所有“行”
  2. 从头到尾再次循环遍历所有“行”

    • 如果列表相同,请忽略它
    • 否则,
  3. 遍历所有“列”:

    • 如果值不相等,请跳转到父循环。
    • 循环后,使用.splice方法删除元素。
  4. 演示:http://jsfiddle.net/EuEHc/

    代码:

    for (var i=0; i<items.length; i++) {
        var listI = items[i];
        loopJ: for (var j=0; j<items.length; j++) {
            var listJ = items[j];
            if (listI === listJ) continue; //Ignore itself
            for (var k=listJ.length; k>=0; k--) {
                if (listJ[k] !== listI[k]) continue loopJ;
            }
            // At this point, their values are equal.
            items.splice(j, 1);
        }
    }
    

答案 2 :(得分:2)

非传统但更易于编码的版本

var items = [['al','bv','sd'],
             ['al','cc','ab'],
             ['cv','vv','sw'],
             ['al','bv','sd']
            ];

var temp = {};

for ( var i in items ) {
    var serialized = JSON.stringify(items[i]);
    if ( temp[serialized] ) {
        items.splice( i, 1 );
        continue;
    }
    temp[serialized] = true;
} 

在这里试试吧! http://jsfiddle.net/y3ccJ/1/

更传统的选择:

var items = [['al','bv','sd'],
             ['al','cc','ab'],
             ['cv','vv','sw'],
             ['al','bv','sd']
            ];

var results = [];

loop: for ( var i in items ) {
    compare: for ( var j in results ) {
        for ( var k in items[i] ) {
            if ( items[i][k] !== results[j][k] ) {
                break compare;
            }
        }
        continue loop;
    }
    results.push( items[i] );
}

http://jsfiddle.net/xhrd6/

答案 3 :(得分:2)

如果您可以使用lodash,这是一个很好的解决方案(请注意,根据您的平台,“require”关键字可能会有所不同,这是在Node.js中使用它的方式):

var _ = require('lodash');
var objects = [['a', 'b', 'c'],['a'],['b', 'a', 'c']];
objects.forEach(innerArr => {
  innerArr.sort();
});
console.log(_.uniqWith(objects, _.isEqual));

这将是输出

[ [ 'a', 'b', 'c' ], [ 'a' ] ]

如果数组中元素的顺序对你很重要,即这个数组['a','b','c']被认为不同于这个['b','a','c'],所有你需要的是删除“排序”部分:

var _ = require('lodash');
var objects = [['a', 'b', 'c'],['a'],['b', 'a', 'c'], ['a','b','c']];
console.log(_.uniqWith(objects, _.isEqual));

这将输出:

[ [ 'a', 'b', 'c' ], [ 'a' ], [ 'b', 'a', 'c' ] ]

答案 4 :(得分:1)

您可以这样做:

var result = [];
result.push(items[0]);
for (i = 1; i < items.length; i++){
    var ok;
    for (j = 0; j < i; j++){
        if (result[j].length != items[i].lenght) continue;
        ok = false;
        for (k = 0; k < items[i].length; k++) if (items[i][k] != result[j][k]) ok = true;
        if (ok == false) break; 
    }
    if (ok) result.push(items[i]);
}
return result;

答案 5 :(得分:1)

function arrays_equal(a,b) { return !!a && !!b && !(a<b || b<a); }

Array.prototype.unique = function() {
    var a = [];
    for (var i = 0, l = this.length; i<l; i++) {
        for (var j = i + 1; j < l; j++) if (arrays_equal(this[i], this[j])) j = ++i;
        a.push(this[i]);
    }
    return a;
};

var ret = items.unique();

demo

答案 6 :(得分:0)

由于这听起来像某种学校作业,我会提供想法而不是代码。您应该考虑人类如何浏览2D阵列并确定其中一个阵列是否唯一。必须查看每一行,每行确定它是否是唯一的。听起来像是嵌套循环给我......

答案 7 :(得分:0)

一个简单的排序和过滤器,函数就可以了。

var items = [
  ['al', 'bv', 'sd'],
  ['al', 'cc', 'ab'],
  ['cv', 'vv', 'sw'],
  ['al', 'bv', 'sd']
];

var temp = ''
var unique = items.sort().filter(r => {
  if (r.join("") !== temp) {
    temp = r.join("")
    return true
  }
})

console.log(unique);