如果两个值都不存在,我如何推入数组?这是我的数组:

[
    { name: "tom", text: "tasty" },
    { name: "tom", text: "tasty" },
    { name: "tom", text: "tasty" },
    { name: "tom", text: "tasty" },
    { name: "tom", text: "tasty" }
]

如果我试图再次推入数组的名字:“tom”或文本:“tasty”,我不希望发生任何事情…但如果这两个都不存在那么我就输入。push()

我该怎么做呢?


当前回答

推送后删除重复项

如果你已经有一个包含重复项的数组,将对象数组转换为字符串数组,然后使用Set()函数消除重复项:

let arr_obj = [
    { name: "tom", text: "tasty" }, 
    { name: "tom", text: "tasty" }
]

let arr_str = arr_obj.map(JSON.stringify)

let arr_unique = [...new Set(arr_str)].map(JSON.parse) 

推前检查

如果你到目前为止没有重复的元素,你想在推入一个新元素之前检查重复:

let arr_obj = [
    { name: "tom", text: "tasty" },
    { name: "tim", text: "tusty" }
]

let new_obj = { name: "tom", text: "tasty" }

let arr_str = arr_obj.map(JSON.stringify)

!arr_str.includes(JSON.stringify(new_obj)) && arr_obj.push(new_obj)

其他回答

我更喜欢使用原生js Array.prototype.some(),即使在jqenv中 文档:w3s some or mdn some

let arr = [
    { name: "tom", text: "tasty" },
    { name: "tom", text: "tasty" }
];
let oneMore = { name: "tom", text: "tasty" };
!arr.some(i => i.name == oneMore.name && i.text == oneMore.text)
  && arr.push(oneMore);

短的例子:

if (typeof(arr[key]) === "undefined") {
  arr.push(key);
}

我的选择是使用.includes()扩展数组。正如@Darrin Dimitrov所建议的原型:

Array.prototype.pushIfNotIncluded = function (element) {
    if (!this.includes(element)) {
      this.push(element);
    }
}

记住include来自es6,在IE上不起作用: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/includes

如果没有结果,可以使用jQuery grep和push: http://api.jquery.com/jQuery.grep/

这基本上是与“扩展原型”解决方案相同的解决方案,但没有扩展(或污染)原型。

我知道这是一个非常老的问题,但如果你使用ES6,你可以使用一个非常小的版本:

[1,2,3].filter(f => f !== 3).concat([3])

非常简单,首先添加一个过滤器,删除项目-如果它已经存在,然后通过concat添加它。

下面是一个更现实的例子:

const myArray = ['hello', 'world']
const newArrayItem

myArray.filter(f => f !== newArrayItem).concat([newArrayItem])

如果你的数组包含对象,你可以像这样调整过滤器函数:

someArray.filter(f => f.some(s => s.id === myId)).concat([{ id: myId }])