我有以下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']
];
答案 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)
你必须循环两次(或三次):
从头到尾再次循环遍历所有“行”
遍历所有“列”:
.splice
方法删除元素。代码:
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] );
}
答案 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);