web-dev-qa-db-ja.com

Array.Push()が存在しない場合

どちらの値も存在しない場合、どうすれば配列にプッシュできますか?これが私の配列です:

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

name: "tom"またはtext: "tasty"のいずれかを使用してもう一度配列にプッシュしようとした場合、何も起こらないようにしたいのですが、どちらもない場合は.Push()にします。

これどうやってするの?

199
tarnfeld

カスタムメソッドを使って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; 
});
94
Darin Dimitrov

文字列の配列(オブジェクトの配列ではない)では、.indexOf()を呼び出すことで項目が存在するかどうかを確認できます。そうでない場合は、Push配列に項目を追加します。

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)
333
Jiří Zahálka

関数を引数として取る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")
62
ashish yadav

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

var cleanArray = $.unique(clutteredArray);

あなたも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;
}
39
MistereeDevlord

これらの理由から、 nderscore.js のようなjsライブラリを使用してください。 Use:union:渡された配列の和集合、つまり1つ以上の配列に存在する一意の項目のリストを順番に計算します。

_.union([1, 2, 3], [101, 2, 1, 10], [2, 1]);
=> [1, 2, 3, 101, 10]
24

このような?

var item = "Hello World";
var array = [];
if (array.indexOf(item) === -1) array.Push(item);

オブジェクトとは

var item = {name: "tom", text: "tasty"}
var array = [{}]
if (!array.find(o => o.name === 'tom' && o.text === 'tasty'))
    array.Push(item)
20
Ron Royston

これは非常に古い質問ですが、ES6を使用している場合は、非常に小さいバージョンを使用できます。

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

非常に簡単です、最初に項目を削除するフィルタを追加します - それがすでに存在する場合は、それから連結を介して追加します。

これがより現実的な例です。

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 }])
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);
6

速度はよくわかりませんが、stringification + indexOfは簡単な方法です。配列を文字列に変換することから始めます。

let strMyArray = JSON.stringify(myArray);

それから一連の属性値ペアのためにあなたが使用できる:

if (strMyArray.indexOf('"name":"tom"') === -1 && strMyArray.indexOf('"text":"tasty"') === -1) {
   myArray.Push({ name: "tom", text: "tasty" });
}

オブジェクト全体を見つける方が簡単です。

if (strMyArray.indexOf(JSON.stringify(objAddMe) === -1) { 
   myArray.Push(objAddMe);
}
4
moshefnord

Arrayプロトタイプを拡張せずに簡単なものが必要な場合は、次のようにします。

// Example array
var array = [{id: 1}, {id: 2}, {id: 3}];

function pushIfNew(obj) {
  for (var i = 0; i < array.length; i++) {
    if (array[i].id === obj.id) { // modify whatever property you need
      return;
    }
  }
  array.Push(obj);
}
3
docta_faustus

Set を使うことをお勧めします。

セットは一意のエントリのみを許可し、自動的に問題を解決します。

集合は次のように宣言できます。

const baz = new Set(["Foo","Bar"])
2
Michael McQuade

誰もがそれほど複雑でない要件を持っている場合には、これが単純な文字列配列に対する答えの私の適応です:

Array.prototype.pushIfNotExist = function(val) {
    if (typeof(val) == 'undefined' || val == '') { return; }
    val = $.trim(val);
    if ($.inArray(val, this) == -1) {
        this.Push(val);
    }
};

更新:IE 8との互換性のためにindexOfを置き換え、jQueryの代替物でトリミングする

2
Scott Beeson

オブジェクトの特定のプロパティで検索したい場合は、map and reduceを使用してこれを実行します。オブジェクトを直接等価にすると失敗することが多いので便利です。

var newItem = {'unique_id': 123};
var searchList = [{'unique_id' : 123}, {'unique_id' : 456}];

hasDuplicate = searchList
   .map(function(e){return e.unique_id== newItem.unique_id})
   .reduce(function(pre, cur) {return pre || cur});

if (hasDuplicate) {
   searchList.Push(newItem);
} else {
   console.log("Duplicate Item");
}
2
Adrian Smith

短い例:

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

FindIndexメソッドは、コールバック関数とその "this"パラメータで使用できます。

注意:古いブラウザはfindIndexを知らないが、ポリフィルは利用可能である。

サンプルコード(元の質問では、新しいオブジェクトがプッシュされたオブジェクトのどちらにもそのデータが含まれていない場合にのみプッシュされるように注意してください)。

var a=[{name:"tom", text:"tasty"}], b;
var magic=function(e) {
    return ((e.name == this.name) || (e.text == this.text));
};

b={name:"tom", text:"tasty"};
if (a.findIndex(magic,b) == -1)
    a.Push(b); // nothing done
b={name:"tom", text:"ugly"};
if (a.findIndex(magic,b) == -1)
    a.Push(b); // nothing done
b={name:"bob", text:"tasty"};
if (a.findIndex(magic,b) == -1)
    a.Push(b); // nothing done
b={name:"bob", text:"ugly"};
if (a.findIndex(magic,b) == -1)
    a.Push(b); // b is pushed into a
1
Simon Hi

これはオブジェクト比較のための機能です。場合によっては、比較するフィールドがたくさんあるかもしれません。単純に配列をループして既存のアイテムと新しいアイテムでこの関数を呼び出します。

 var objectsEqual = function (object1, object2) {
        if(!object1 || !object2)
            return false;
        var result = true;
        var arrayObj1 = _.keys(object1);
        var currentKey = "";
        for (var i = 0; i < arrayObj1.length; i++) {
            currentKey = arrayObj1[i];
            if (object1[currentKey] !== null && object2[currentKey] !== null)
                if (!_.has(object2, currentKey) ||
                    !_.isEqual(object1[currentKey].toUpperCase(), object2[currentKey].toUpperCase()))
                    return false;
        }
        return result;
    };
0
user3180914

私はここで答えるには遅すぎると思いますが、これは私が書いたメールマネージャーのためについに思いついたものです。必要なのはそれだけです。

window.ListManager = [];
$('#add').click(function(){
//Your Functionality
  let data =Math.floor(Math.random() * 5) + 1 
  
  if (window.ListManager.includes(data)){
      console.log("data exists in list")
  }else{
       window.ListManager.Push(data);
  }
  
  
  $('#result').text(window.ListManager);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<h1>Unique List</h1>

<p id="result"></p>
<button id="add">Add to List</button>
0
TheeCodeDragon