【问题标题】:Javascript - remove duplicate objects from an arrayJavascript - 从数组中删除重复的对象
【发布时间】:2014-06-25 02:50:18
【问题描述】:

我正在构建一个涉及创建对象数组的应用程序,类似于:

var foo = [{
'foo' : 'foo1' 
},
{
'foo' : 'foo2' 
},
{
'foo' : 'foo3' 
}];

然后有一个 HTML 表单,用户可以在其中填写新对象的值。提交表单时,新值被推送到数组中。我想要的是一个 if/else 语句,它检查新对象是否已经存在于数组中。 所以像:

document.getElementById('form').addEventListener('submit',function(){
var newObject = {'foo' : input value goes here }
if (//Checks that newObject doesn't already exist in the array) {
    foo.push(newObject)
}
else {
//do nothing
}
});

值得注意的是,我正在使用 Angular

【问题讨论】:

  • 只需使用Object 而不是Array
  • ECMAScript 6 为您提供.find() 方法。 if (foo.find(function(obj) { return obj.foo === newObject.foo; }) === undefined) { foo.push(newObject); }
  • 在这种情况下 [].find() 比 [].some() 好吗?

标签: javascript arrays forms angularjs object


【解决方案1】:

您必须遍历 foo 数组并检查是否有任何重复项。

document.getElementById('form').addEventListener('submit',function(){
    var newObject = {'foo' : input value goes here }
    if (!isInArray(foo, newObject, 'foo')) {
        foo.push(newObject)
    }
});
function isInArray(arr, newObj, type) {
    var i, tempObj, result = false;
    for (i = 0; i < arr.length; i += 1) {
        tempObj = arr[i];
         if (tempObj[type] === newObj[type]) {
            result = true;
        }
    }
    return result;
}

如果您的数组不包含对象,它会更容易和更快。然后,您只需将 if 子句设置为:

document.getElementById('form').addEventListener('submit',function(){
    var newString = "foo bar";
    if (foo.indexOf(newString) === -1) {
        foo.push(newString);
    }
});

【讨论】:

    【解决方案2】:

    您可以使用这种方法:

    你需要:

    1. 了解如何比较 2 个对象。
    2. 循环执行。

    如何比较 2 个对象。

    其中一种方法是:

    JSON.stringify(obj1) === JSON.stringify(obj2) 
    

    注意,这样比较对象不好:

    序列化对象只是为了比较是非常昂贵的,而且不 保证可靠

    正如本文中 cmets 中提到的 cookie 怪物。 我只是建议它,以实现您想要的。您可以找到更好的变体。你可以找到一些漂亮的答案here

    如何在循环中做到:D

    你的情况是:

    function checkIfObjectExists(array, newObject) {
        var i = 0;
        for(i = 0; i < array.length; i++ ) {
            var object = array[i];
            if(JSON.stringify(object) === JSON.stringify(newObject)) 
            {
                return true;
            }   
        }
        return false;
    }
    

    另外,我添加了函数,所以你可以在你的代码中使用它。

    现在将其添加到您的代码中:

    if (checkIfObjectExists(foo, newObject)) {
        // objects exists, do nothing
    }
    else {
        foo.push(newObject);
    }
    

    DEMO

    【讨论】:

    • 序列化对象只是为了比较是非常昂贵的,并且不能保证是可靠的。此外,我们不知道是所有属性都应该匹配还是只匹配一个。在数组上使用for-in 通常被认为是一种不好的做法。最后,您将在函数中创建一个隐式全局变量。
    • 我只是建议了序列化对象的方法并提供了指向源的链接,他可以在其中找到其他方法。 +。不知道for-in——为什么会这样;我在哪里可以读到它?我编辑了我的答案;现在是正确的吗?
    • 它更慢,它不能保证绝对的顺序,如果Array.prototype 被扩展,它会影响这些属性。因此,在使用传统的for 循环时,如果没有这样的问题,对它的攻击太多了,因此不值得。但不要忘记varitem 之前。这就是创建隐式全局的地方。
    • @cookiemonster,感谢您的解释。下一次,我将使用 for (现在将编辑我的答案)。另外,我用item 变量编辑了问题。
    • @cookiemonster 还删除了for-in 循环并添加了for 循环+提到了序列化对象。谢谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-06-19
    • 2020-10-25
    • 2018-01-08
    • 2018-08-15
    • 2021-12-30
    • 2016-09-24
    相关资源
    最近更新 更多