【问题标题】:Compare two multidimensional arrays in javascript比较javascript中的两个多维数组
【发布时间】:2012-11-20 23:41:50
【问题描述】:

我有两个数组:

var array_old = [{id:"5436", title:"I Like you boy"}, {id:"5437", title:"Hello how are you"}];
var array_new = [{id:"5436", title:"I Like you boy"}, {id:"1132", title:"I'm fine"}];

$.each(array_old, function(id, array)
{
    if(!$.inArray(array['id'], array_new, 1)>-1){
        alert(array['id'] + " does not exist in array_new");
    }
});

我想检查array_old的ID是否存在于array_new中,所以我希望在这个例子中代码输出“5437在array_new中不存在”。

我找不到任何可以让我这样做的功能,那我该怎么做呢?

【问题讨论】:

  • 有什么问题???你是说你期待它到alert(),但它没有这样做?因为确实如此:jsfiddle.net/VHb3Q
  • @meetamit 它还说 5436 不存在,但它确实存在,所以脚本不起作用
  • 您是否希望数组的顺序相同?可以对它们进行排序吗?

标签: javascript jquery arrays


【解决方案1】:

http://jsfiddle.net/tppiotrowski/VHb3Q/2/

var array_old = [{
    id: "5436",
    title: "I Like you boy"},
{
    id: "5437",
    title: "Hello how are you"}];
var array_new = [{
    id: "5436",
    title: "I Like you boy"},
{
    id: "1132",
    title: "I'm fine"}];

$.each(array_old, function(old_index, old_obj) {
    var old_id = old_obj['id'];
    var found = false;
    $.each(array_new, function(new_index, new_obj) {
        if (new_obj['id'] == old_id) {
            found = true;
        }
    });
    if (!found) {
        alert(old_id + " does not exist in array_new");
    }
});​

【讨论】:

    【解决方案2】:

    我自己找到了一种方法,但我不知道这是否是最好的方法:

    var array_old = [{id: "5436",title: "I Like you boy"},{id: "5437",title: "Hello how are you"},{id: "5438",title: "Hello how are you2"}];
    var array_new = [{id: "5436",title: "I Like you boy"},{id: "1132",title: "I'm fine"}];
    
    $.each(array_old, function(id, array){
    
        found = 0;
    
        $.each(array_new, function(id2, array2) {
    
            if(array['id']==array2['id'])
            {
                found++;
            }
    
        });
    
        if(found==0)
        {
            alert(array['id']+' does not exist in array_new');
        }
    
    });
    

    http://jsfiddle.net/FAb3k/2/

    【讨论】:

    • 该解决方案看起来可以接受。您可能想说var found = 0; 将变量保留在本地范围内,从而防止它污染全局命名空间。
    • 您可以使用return false 打破each 循环,以便在找到值时也提高性能
    【解决方案3】:

    取决于您的阵列有多大 - 您可能希望使用性能更高的解决方案。

    • 最简单的解决方案(您和@Tebb 都找到了)有Θ(n*m)
    • 如果你能稍微优化一下(如果你没有[未]找到该元素,则中断 - 请参阅@gonchuki),你仍然在O(n*m)
    • 您可以假设两个数组的顺序相同,并且只运行一个循环:O(min(n,m))。如果您需要在此之前对它们进行排序,您会得到O(n*log n+m*log m)
    • 最好使用哈希表进行O(1) 查找,得到O(n+m)。您可以轻松地为此使用 JS 对象:
    var counts = {};
    for (var i=0; i<array_new.length; i++)
        counts[array_new[i].id] = (counts[array_new[i].id] || 0) + 1;
    
    return array_old.every(function(item) {
        return item.id in counts && counts[item.id]--;
    });
    

    (Demo)

    【讨论】:

    • 你能在 jsfiddle 中实现这个吗?
    • 我能想到的最多的是“return array_old.every”给了我们一个值是否一个项目被索引计数......但是当前版本返回false......这不是非常有用
    • 它不会将 KV 对放在 counts 中,而只会将您要查找的键 (ids) 放在其中。它对每个 id 进行计数(通常会导致1),然后要求array_old 中的每个项目都具有正计数(并减少它以检测多次出现)。如果数组不匹配则返回false,否则返回true
    【解决方案4】:

    仅仅因为它有效并且最终更易于阅读而抛出一个疯狂的替代方案(不知道性能,但让我们跳过它,因为我这样做是为了展示另一种方法)

    var ids_old = $.map(array_old, function(item) { return item.id; });
    var ids_new = $.map(array_new, function(item) { return item.id; });
    
    var duplicates = $.grep(ids_old, function(i, id) { 
        return $.inArray(id, ids_new) !== -1;
    });
    

    请注意,最终结果是您会获得重复 ID 本身的列表,这种另一种方法可以让您自己收集项目:

    var ids_new = $.map(array_new, function(item) { return item.id; });
    
    var duplicates = $.grep(array_old, function(i, item) { 
        return $.inArray(item.id, ids_new) !== -1;
    });
    

    加分:即使他的示例是纯 jQuery,请注意在兼容 ECMAScript5 的浏览器上,您可以使用本地数组对应物来实现相同的结果。

    【讨论】:

      猜你喜欢
      • 2013-05-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-06-27
      相关资源
      最近更新 更多