如果不存在Array.push()?

tar*_*eld 226 javascript arrays json push not-exists

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

[
    { name: "tom", text: "tasty" },
    { name: "tom", text: "tasty" },
    { name: "tom", text: "tasty" },
    { name: "tom", text: "tasty" },
    { name: "tom", text: "tasty" }
]
Run Code Online (Sandbox Code Playgroud)

如果我试图再次推到与在阵列name: "tom"text: "tasty",我不希望发生什么事......但是,如果这两个时间都不存在那么我想它.push()

我怎样才能做到这一点?

Jiř*_*lka 381

对于字符串数组(但不是对象数组),您可以通过调用检查项是否存在.indexOf(),如果不存在,则只需项目入数组:

var newItem = "NEW_ITEM_TO_ARRAY";
var array = ["OLD_ITEM_1", "OLD_ITEM_2"];

array.indexOf(newItem) === -1 ? array.push(newItem) : console.log("This item already exists");

console.log(array)
Run Code Online (Sandbox Code Playgroud)

  • 不确定为什么这不被标记为正确.它不使用任何外部,不需要创建扩展并且很简单.操作问题的完美答案. (42认同)
  • 在最初的问题中,数组的值是对象,而不是字符串(如果值是对象,则此解决方案不起作用). (32认同)
  • 应该删除这个答案,因为它客观上是错误的,但仍然吸引了最多的赞成. (13认同)
  • @EmilPedersen - 不是真的.尝试`if(a.indexOf({name:"tom",text:"tasty"})!= - 1)a.push({name:"tom",text:"tasty"})`两次.它会两次添加一个"相似"的对象. (11认同)
  • 这可以使用一组对象 (5认同)
  • 这不是正确答案,为什么会被接受?它仅适用于Js数组,不适用于数组内的对象。 (2认同)

Dar*_*rov 105

您可以使用自定义方法扩展Array原型:

// check if an element exists in array using a comparer function
// comparer : function(currentElement)
Array.prototype.inArray = function(comparer) { 
    for(var i=0; i < this.length; i++) { 
        if(comparer(this[i])) return true; 
    }
    return false; 
}; 

// adds an element to the array if it does not already exist using a comparer 
// function
Array.prototype.pushIfNotExist = function(element, comparer) { 
    if (!this.inArray(comparer)) {
        this.push(element);
    }
}; 

var array = [{ name: "tom", text: "tasty" }];
var element = { name: "tom", text: "tasty" };
array.pushIfNotExist(element, function(e) { 
    return e.name === element.name && e.text === element.text; 
});
Run Code Online (Sandbox Code Playgroud)

  • 我想知道为什么这不是语言的原生 - 忘记它是如何实现的 - "只添加唯一"的想法是如此基本以至于假设存在. (21认同)
  • 直接扩展内置对象是一种不好的做法。 (10认同)
  • 最好使用JavaScript 1.6方法IndexOf而不是inArray扩展Array原型. (9认同)
  • 我认为您的camparer(比较器?)应该采用两个参数,这将简化添加值为内联而不是您可以在函数中访问的变量的情况.array.pushIfNotExist({name:"tom",text:"tasty"},function(a,b){return a.name === b.name && a.text === b.text;}); (5认同)
  • `Array.findIndex()`是一个内置的JS函数,它将实现与代码相同的功能. (5认同)

ash*_*dav 81

使用Array.findIndex函数很容易,它将函数作为参数:

var a = [{name:"bull", text: "sour"},
    { name: "tom", text: "tasty" },
    { name: "tom", text: "tasty" }
]
var index = a.findIndex(x => x.name=="bob")
// here you can check specific property for an object whether it exist in your array or not

if (index === -1){
    a.push({your_object});
}
else console.log("object already exists")
Run Code Online (Sandbox Code Playgroud)

  • 这就是答案! (6认同)
  • 最相关的是在数组中添加元素(如果不存在) (2认同)

Mis*_*ord 40

http://api.jquery.com/jQuery.unique/

var cleanArray = $.unique(clutteredArray);
Run Code Online (Sandbox Code Playgroud)

你可能也对makeArray感兴趣

前面的例子最好说在推送之前检查它是否存在.事后我看到它还声明你可以将它声明为原型的一部分(我猜这也就是类扩展),所以下面没有大的改进.

除了我不确定indexOf是否是更快的路线然后inArray?大概.

Array.prototype.pushUnique = function (item){
    if(this.indexOf(item) == -1) {
    //if(jQuery.inArray(item, this) == -1) {
        this.push(item);
        return true;
    }
    return false;
}
Run Code Online (Sandbox Code Playgroud)

  • 从jQuery链接:`注意,这只适用于DOM元素的数组,而不是字符串或数字.此外,indexOf在IE8中不起作用:( (22认同)

Ron*_*ici 24

出于这些原因,请使用像underscore.js这样的js库.使用:union:计算传入数组的并集:按顺序存在于一个或多个数组中的唯一项列表.

_.union([1, 2, 3], [101, 2, 1, 10], [2, 1]);
=> [1, 2, 3, 101, 10]
Run Code Online (Sandbox Code Playgroud)

  • 注意,这将返回一个新数组,并不实际推送到现有数组. (8认同)
  • 恕我直言,真的没有必要引入一个框架来测试这么简单的东西 (3认同)

Ron*_*ton 24

像这样?

var item = "Hello World";
var array = [];
if (array.indexOf(item) === -1) array.push(item);
Run Code Online (Sandbox Code Playgroud)

有了对象

var item = {name: "tom", text: "tasty"}
var array = [{}]
if (!array.find(o => o.name === 'tom' && o.text === 'tasty'))
    array.push(item)
Run Code Online (Sandbox Code Playgroud)

  • `array.find`是一个坏主意,因为它搜索整个数组.使用`findIndex`,它只搜索到第一次出现. (4认同)
  • @ K48根据这个:/sf/answers/2363170141/"找到"停止后找到该项目 (3认同)

Eri*_*ero 22

简单的代码,如果 'indexOf' 返回 '-1',则表示该元素不在数组内,则条件 '=== -1' 检索真/假。

'&&' 运算符的意思是 'and',所以如果第一个条件为真,我们将它推送到数组中。

array.indexOf(newItem) === -1 && array.push(newItem);
Run Code Online (Sandbox Code Playgroud)

  • 我认为这是一个很好的答案,也是一个更好的解决方案,所以我投了赞成票。我不明白@help-info.de 的评论,特别是因为这里还有其他很糟糕的答案。 (4认同)

Mic*_*ade 17

我建议你使用Set

集合只允许唯一的条目,这会自动解决您的问题。

集合可以这样声明:

const baz = new Set(["Foo","Bar"])
Run Code Online (Sandbox Code Playgroud)


Mic*_*idl 14

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

[1,2,3].filter(f => f !== 3).concat([3])
Run Code Online (Sandbox Code Playgroud)

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

这是一个更现实的例子:

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

myArray.filter(f => f !== newArrayItem).concat([newArrayItem])
Run Code Online (Sandbox Code Playgroud)

如果您的数组包含对象,您可以调整过滤器函数,如下所示:

someArray.filter(f => f.some(s => s.id === myId)).concat([{ id: myId }])
Run Code Online (Sandbox Code Playgroud)

  • 这里是一个很好的解决方案。谢谢! (2认同)

Gop*_*ika 10

动态推送

var a = [
  {name:"bull", text: "sour"},
  {name: "tom", text: "tasty" },
  {name: "Jerry", text: "tasty" }
]

function addItem(item) {
  var index = a.findIndex(x => x.name == item.name)
  if (index === -1) {
    a.push(item);
  }else {
    console.log("object already exists")
  }
}

var item = {name:"bull", text: "sour"};
addItem(item);
Run Code Online (Sandbox Code Playgroud)

用简单的方法

var item = {name:"bull", text: "sour"};
a.findIndex(x => x.name == item.name) == -1 ? a.push(item) : console.log("object already exists")
Run Code Online (Sandbox Code Playgroud)

  • 祝您双手健康。简单而美丽的解决方案@Gopala Raja Naika (2认同)
  • 这个 a.findIndex(x =&gt; x.name == item.name) 非常简单而且非常有用。谢谢 (2认同)

Aug*_*res 5

我的选择是.includes()按照@Darrin Dimitrov 的建议使用扩展 Array.prototype:

Array.prototype.pushIfNotIncluded = function (element) {
    if (!this.includes(element)) {
      this.push(element);
    }
}
Run Code Online (Sandbox Code Playgroud)

只记得includes来自 es6 并且不适用于 IE:https : //developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/includes