0

我有两个数组(data 和 data_not_included)。这些数组的每个元素都有属性 ID 和名称。我这样填充它们:

data[i] = {
           name :products.models[i].get('name'),
           id :  products.models[i].get('id')
          };

现在我想显示数据中不在 data_not_included 数组中的元素。例如我有

data=[{name: Sugar}{id: 1},{name: Butter}{id: 2},{name: Cola}{id: 3}]
// and
data_nat_included = [{name: Sugar}{id: 1},{name: Butter}{id: 2}].

它应该{name: Cola}{id: 3}只显示。

这是我已经做的:

for(var j=0;j<data_not_icluded.length;j++)
{
    for(var i=0;i<data.length;i++)
    {
        if(data[i].id != data_not_icluded[j].id ){
          //but this doesnt work for me it displayes a lot of element many times
        }
     }
}
4

3 回答 3

1

这两个答案都是渐近错误的。这意味着它们在次优时间运行。换句话说,它们是解决问题的幼稚方法。这个问题在数据库领域更广为人知,其中连接操作是司空见惯的。众所周知,连接的复杂性是第一个表O(log n * n + log m * m)中元素的数量和第二个表中元素的数量。这比其他示例中提供的简单解决方案所需的操作更少。nmO(n^2)

但是,如果对您的数据有更多了解,例如,我希望这些值是唯一的并且易于序列化为字符串,您甚至可以O(n + m)通过简单地创建要比较的对象的哈希来降低复杂性。这是如何做到的:

其中n是第一个数组m中的元素数, 是第二个数组中的元素数。

var data = [{ name: "Sugar" },
            { id: 1 },
            { name: "Butter" },
            { id: 2 },
            { name: "Cola" },
            { id: 3 }];
var dataNatIncluded = [{ name: "Sugar" },
                       { id: 1 },
                       { name: "Butter" },
                       { id: 2 }];

function join(a, b) {
    var hashA = {}, hashB = {}, p, result = [];
    function setter(hash) {
        return function (element) { hash[JSON.stringify(element)] = element; };
    }
    a.forEach(setter(hashA));
    b.forEach(setter(hashB));
    for (p in hashB) delete hashA[p];
    for (p in hashA) result.push(hashA[p]);
    return result;
}
// [{ name: "Cola" }, { id: 3 }]
于 2013-10-12T21:28:23.747 回答
0

一个简单的方法来做到这一点:

var vals = [];

for(var i=0;i<data.length;i++)
{
    var found = false;
    for(var j=0;j<data_nat.length;j++)
    {
        if(data[i].id == data_nat[j].id ){
          found = true;
          break;
        }
     }
    if (!found) vals.push(data[i]);
}

JSFiddle

于 2013-10-12T13:29:51.103 回答
0
for(var j=0;j<data_not_icluded.length;j++)
    for(var i=0;i<data.length;i++)
        if(data[i].id != data_not_icluded[j].id )

想想这是做什么的:对于任何未包含的对象,显示与当前未包含的对象具有不同 id 的所有对象。这将多次显示许多项目,并将显示“未包含”但位于另一个位置的对象。

相反,循环data,检查每个它不包含在 中data_not_included,否则显示它:

dataloop: for (var i=0; i<data.length; i++) {
    for (var j=0; j<data_not_included.length; j++)
        if (data[i].id == data_not_icluded[j].id)
            continue dataloop;
    display(data[i]);
}

或者,使用Arrays 的一些迭代方法

data.filter(function(d) {
    return data_not_included.every(function(n) {
        return d.id != n.id;
    });
}).each(display);
于 2013-10-12T13:34:58.363 回答