【问题标题】:find unique items in a set of arrays and remove non-uniques from arrays found在一组数组中查找唯一项并从找到的数组中删除非唯一项
【发布时间】:2011-09-10 17:44:02
【问题描述】:

给定一个对象,其中 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];
...

现在,我想将我的对象缩小到这个范围,通过检查数组中的任何数字是否只出现在这个数组中,而不是在其他值的数组中,然后消除里面的所有其他数字保存唯一编号的特定数组。
(规则:给定数组内没有重复,因此无需检查):

// 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 是一个唯一的数字,不会出现在另一个数组中。

我无法为此考虑一个有效的模式......

【问题讨论】:

  • 那么就像两个集合的交集的恭维(如果你认为数组是集合)?
  • 这个问题我仔细看了4遍还是看不懂问题。
  • 是的,这有点复杂。我不确切知道如何实施解决方案来更改给定的对象以匹配所需的结果......仍然不清楚?
  • 看不懂就没法回答了;)
  • 如您所见,有一个示例对象和一个结果对象,答案是从示例状态到结果状态的方式。这里的关键是消除一个值数组中的所有数字,如果数组中的一个数字在所有其他值的数组中是唯一的...

标签: javascript


【解决方案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);
});

Demo

对象 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;
    }
});

Demo

【讨论】:

  • 如何输出符合所需结果规则的对象?
  • 因为被修改的值(数组)只是在所有其他数组中具有完全唯一编号的值。没有注意只有 0,3 在它的值数组中有数字“1”,用于消除其中的所有其他数字。这就是这种转换的规则。
  • “现在,我想通过检查数组中的任何数字是否仅出现在此数组中,而不出现在对象的其他部分中,来缩小我的对象范围。” - 意味着如果数组中的任何数字出现在任何其他数组中,它都会被消除。我仍然不明白 0,4 的逻辑是 [6, 8]。也许你可以解释更多。确保更新问题本身。
  • 我写了“......然后消除包含唯一数字的特定数组中的所有其他数字”,因此只消除包含唯一数字的数组
  • 现在我看到了更新后的要求。我想我明白了。稍后我会更新逻辑。
【解决方案2】:

这个想法是使用桶, 认为这是一个有趣的实验,我知道代码可以优化,而且不是那么漂亮,但它解决了问题,而且效率并不低:

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);

【讨论】:

    【解决方案3】:

    长篇大论 (jsfiddle)

    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 解决方案。否则,上述内容在解释和准确性方面都应该做得很好。

    编辑:这已被修改为递归过滤结果。

    【讨论】:

    • 你的答案/解决方案比我的更复杂.. 但我喜欢 Avi Pinto 的解决方案。
    • 除了我的解决方案之外,没有一个解决方案最终得到我所展示的独特集合。我会说 Avi 和我有类似的方法。如果你觉得我的很复杂,那么我建议你放弃编程。这几乎是最简单的了。可能令人困惑的是使用 reverse-for 循环,它用于提高性能,因为它与 reverse-while 相当。
    • 我建议你重新阅读这篇文章,因为它类似于 Avi 的解决方案,但包括更多必要的步骤和更多的优化,我们之间的主要区别似乎是最终的 for 循环.剩下的优化将包括对数组进行排序并在您遇到大于最大唯一性的数字时打破 for 循环。
    • 您已经更改了一些所需的输出,因此它将包括一个裸对系统,以消除其他单元格的可能性数组中的所有 68 .. 这是我也需要,但它本身被认为是一种方法..感谢您的解决方案!读起来很有趣!
    • 我认为它仍然比需要的复杂得多。检查我的解决方案,我已经改进了它
    【解决方案4】:

    我会创建一个单独的一维数组来跟踪多维数组中的值。

    遍历多维数组中的每个值。如果一维数组中不存在该值,则将其添加到一维数组中并保留在多维数组中。如果值 DOES 存在于单维数组中,只需将其从多维数组中移除并移至下一个值。

    【讨论】:

    • 它不会那样工作,它会删除比需要更多的数字。我需要删除数组中唯一的数字旁边的所有数字..
    【解决方案5】:

    这里的想法是我遍历每个数组中的每个数字,并对照它进行检查
    一个桶(字符串),它包含所有数组中的所有数字,加入。如果桶中当前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]
    */
    

    【讨论】:

    • 函数调用是效率最低的解决方案之一,如果寻求性能,我会远离它。
    • 我更多的是寻找一个漂亮的解决方案,它包含尽可能少的代码行,但仍然可以理解(不压缩或任何东西)
    • 我已经完善了我的代码,我认为现在它是最好的解决方案,因为它速度快,而且我认为它几乎可以做到尽可能小
    • 我不认为它比我的更快,而且我的仍然没有优化(尽管你不会真正看到区别),但是使用 jQuery,它是浓缩的。对于那个论点,如果您在代码中包含 jQuery 方法,您会发现它更大且更令人困惑 :) 另外,我不认为 indexOf 是跨浏览器的,至少它不是一次,这就是我没有使用它的原因;这将取代我的循环之一。我说选择任何对你来说更容易理解的东西。
    • 另外,请注意,为了终止递归,您必须确保以某种方式修改了原始对象。这可以使用一个标志(如我所做的)或将初始对象与返回的对象进行比较来完成,这将使您的内存加倍并增加处理时间。这也可能是为什么我的看起来更杂乱。无论如何,你的工作,我很高兴你找到了解决方案
    猜你喜欢
    • 1970-01-01
    • 2011-12-13
    • 2018-07-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-02-09
    • 2013-08-30
    • 1970-01-01
    相关资源
    最近更新 更多