[英]find unique items in a set of arrays and remove non-uniques from arrays found
给定一个 object,其中Key作为一个数组(位置), Value作为一个数组:
// Example Object
0,2 : [6, 8, 9]
0,3 : [1, 6, 8]
0,4 : [6, 8]
0,5 : [6, 8]
0,6 : [4, 5, 8, 9]
0,7 : [5, 8]
0,8 : [4, 5, 7, 9]
(它是这样创建的:
x = {};
x[[0,2]] = [6, 8, 9];
x[[0,3]] = [1, 6, 8];
...
现在,我想将我的 object 缩小到这个范围,方法是检查 Array 中的任何数字是否仅出现在该数组中,而不出现在其他值的 arrays 中,然后消除包含唯一编号的特定数组中的所有其他数字。
(规则:在给定的数组中没有重复,所以不需要检查):
// Result Object
0,2 : [6, 8, 9]
0,3 : [1]
0,4 : [6, 8]
0,5 : [6, 8]
0,6 : [4, 5, 8, 9] // now 4 becomes also a "loner"
0,7 : [5, 8]
0,8 : [7]
所以在 Key [0,3] 中,Value 的数组被缩小到只有 [1],因为 1 是一个唯一的数字,不会出现在另一个数组中。
我很难想到一个有效的模式......
不明白为什么 0,4 是 [6, 8]。 6 和 8 都已经出现在 0,2: [6, 8, 9] 中。
u = [];
$.each(x, function(i, arr){
//console.log(arr);
x[i] = $.grep(arr, function(elem, i){
return ($.inArray(elem, u) == -1);
});
$.merge(u, arr);
});
Object x 被修改为
0,2: [6, 8, 9]
0,3: 1
0,4:[]
0,5:[]
0,6: [4, 5]
0,7:[]
0,8: [7]
$.each(x, function(i, arr){
u = [];
$.each(x, function(j, arrJ){
$.merge(u, i == j ? [] : arrJ);
});
var ue = null;
$.each(arr, function(i, elem){
if ($.inArray(elem, u) == -1) {
ue = elem;
}
});
if (ue != null){
arr.length = 0;
arr[0] = ue;
}
});
这个想法是使用存储桶,认为这是一个有趣的实验,我知道代码可以优化,而且不是那么漂亮,但它解决了问题,而且效率并不低:
var x = {}; // object
x[[0,2]] = [6, 8, 9];
x[[0,3]] = [1, 6, 8];
x[[0,4]] = [6, 8];
x[[0,5]] = [6, 8];
x[[0,6]] = [4, 5, 8, 9];
x[[0,7]] = [5, 8];
x[[0,8]] = [4, 5, 7, 9];
var trackCount = [];
for(var key in x){
for(var j in x[key]){
// console.log(key);
if(typeof(trackCount[x[key][j]]) === "undefined"){
trackCount[x[key][j]] = [];
}
// trackCount[x[key][j]].push(trackCount[x[key]]);
trackCount[x[key][j]].push(key);
}
}
//console.log(trackCount)
for(var i=0;i<trackCount.length;++i){
if(trackCount[i] && trackCount[i].length == 1){
x[trackCount[i][0]] = [];
x[trackCount[i][0]].push(i)
}
}
console.log(x);
var sudoku = { '0,2' : [6,8,9]
, '0,3' : [1,6,8]
, '0,4' : [6,8]
, '0,5' : [6,8]
, '0,6' : [4,5,8,9]
, '0,7' : [5,8]
, '0,8' : [4,5,7,9]
};
var finished = false;
while (!finished) {
var unique = {};
finished = true;
// Build Unique Numbers List
for (var section in sudoku)
for (var pos = sudoku[section].length; pos--; ){
if (typeof unique[ sudoku[section][pos] ] === "undefined")
unique[ sudoku[section][pos] ] = [];
unique[sudoku[section][pos]].push(section);
}
// Clean Up Unique Numbers List
for (var num in unique)
if (unique[num].length > 1)
delete unique[num];
// Remove non-Uniques
var is_unique = false;
for ( var num in unique )
for ( var pos = sudoku[ unique[num] ].length; pos--; ){
is_unique = false;
for (var unique_value in unique)
if (sudoku[ unique[num] ][pos] == unique_value){
is_unique = true;
break;
}
if (!is_unique){
sudoku[ unique[num] ].splice(pos,1);
finished = false;
}
}
}
console.clear();
console.dir(unique);
console.dir(sudoku);
/**/
{数独}
[0,2]:[9]
[0,3]: [1]
[0,4]: [6, 8]
[0,5]: [6, 8]
[0,6]: [4]
[0,7]: [5]
[0,8]: [7]
注意:这不是最优化的算法,但由于这是针对数独的,因此性能不会真正受到您选择的任何算法的影响。 所以,为了简洁,我会选择 amit_g 的 jQuery 解决方案。 否则,上述内容对于解释和准确性都应该很好。
编辑:这已被修改为递归过滤结果。
我将创建一个单独的单维数组来跟踪多维数组中的值。
遍历多维数组中的每个值。 如果一维数组中不存在该值,则将其添加到一维数组中,并保留在多维数组中。 如果该值确实存在于单维数组中,只需将其从多维数组中删除并移至下一个值。
这里的想法是我 go 通过每个数组中的每个数字,并检查它
一个包含来自所有 arrays 的所有数字的存储桶(字符串),已加入。 如果存储桶中当前x[key][i]
的第一个索引与最后一个索引相同,则意味着该数字是唯一的,因此它的持有数组被重置为单独保存该数字。
var x = {}; // object
x[[0,0]] = [6, 8, 9];
x[[0,1]] = [1, 6, 8];
x[[0,2]] = [6, 8];
x[[0,3]] = [6, 8];
x[[0,4]] = [4, 5, 8, 9];
x[[0,5]] = [5, 8];
x[[0,6]] = [4, 5, 7, 9];
function findUniquePosibilites(x){
var bucket = "";
for(var key in x)
bucket += x[key].join("");
for(var key in x)
for (var i = x[key].length; i--; ){
var num = x[key][i];
if( bucket.indexOf(num) == bucket.lastIndexOf(num) ){
x[key] = [num];
break;
};
}
}
findUniquePosibilites(x);
console.dir( x );
/*
0,0 : [6, 8, 9]
0,1 : [1]
0,2 : [6, 8]
0,3 : [6, 8]
0,4 : [4, 5, 8, 9]
0,5 : [5, 8]
0,6 : [7]
*/
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.