web-dev-qa-db-ja.com

JavaScriptの配列に一意のオブジェクトのみを追加します

私はこれから始めるとしましょう:

var shippingAddresses =      [{
                                "firstname": "Kevin",
                                "lastname": "Borders",
                                "address1": "2201 N Pershing Dr",
                                "address2": "Apt 417",
                                "city": "Arlington",
                                "state": "VA",
                                "Zip": "22201",
                                "country": "US"
                            }, {
                                "firstname": "Dan",
                                "lastname": "Hess",
                                "address1": "304 Riversedge Dr",
                                "address2": "",
                                "city": "Saline",
                                "state": "MI",
                                "Zip": "48176",
                                "country": "US"
                            }];

これを使用して、フォームに事前入力します。ユーザーはエントリを編集したり、新しいエントリを追加したりできます。重複を追加しないようにする必要があります。

問題は、シリアル化するフォームの構造と、これらの値がデータベースから返される順序が同じではないため、次の形式でこの配列にアイテムを挿入する可能性があることです。

                            {
                                "country": "US",
                                "firstname": "Kevin",
                                "lastname": "Borders",
                                "address1": "2201 N Pershing Dr",
                                "address2": "Apt 417",
                                "Zip": "22201",                                    
                                "city": "Arlington",
                                "state": "VA"
                            }

これは最初のエントリと同じですが、順序が異なります。

私はunderscorejsをロードしていますので、そのライブラリでそれを処理する方法があれば素晴らしいでしょう。それが役立つ場合は、jQueryも使用しています。

この時点で、どのように進むべきか分かりません。

17
S16

nderscore findWhere function は、必要なことを正確に行います-オブジェクトIDによるindexOf検索ではなく、プロパティが入力と同じ値を持つオブジェクトを検索します。

if (_.findWhere(shippingAddresses, toBeInserted) == null) {
    shippingAddresses.Push(toBeInserted);
}
28
Bergi

lodashnion メソッドを使用した基本的な例:

var a = [1,2,3];

// try to add "1" and "4" to the above Array
a = _.union(a, [1, 4]);

console.log(a);
<script src="//cdnjs.cloudflare.com/ajax/libs/lodash.js/4.13.1/lodash.min.js"></script>

これは質問に直接答えるわけではありませんが、一意の値を配列に追加する方法に関するより広範な質問に答えます。私のように、他の人がこのページにグーグルからつまずくかもしれません。

15
vsync

この答えに基づいて: "js-remove-an-array-element-by-index-in-javascript"

https://stackoverflow.com/a/7142909/886092

簡潔で、underscore.jsや他のフレームワークを必要としない次のイディオムを使用しています。

DataTables jqueryプラグインの選択された行と選択解除された行を記録する例を次に示します。現在選択されているIDの配列を保持していますが、配列内で重複することはありません。

coffeescriptで

  fnRowSelected: (nodes) ->
    position = $selected.indexOf(nodes[0].id)
    unless ~position
      $selected.Push nodes[0].id
    return
  fnRowDeselected: (nodes) ->
    position = $selected.indexOf(nodes[0].id)
    if ~position
      $selected.splice(position, 1)

より一般的には

position = myArray.indexOf(myval)
unless ~position
  myArray.Push myVal

またはJSで

var position;

position = myArray.indexOf(myval);

if (!~position) {
  myArray.Push(myVal);
}
3
Ashley Raiteri

編集、これはソートされていないプロパティの例で動作します:

var normalized_array = _.map(shippingAddresses, function(a){ 
      var o = {}; 
      _.each(Object.keys(shippingAddresses[0]), function(x){o[x] = a[x]});
      return o;
})
var stringy_array = _.map(normalized_array, JSON.stringify);
shippingAddresses = _.map(_.uniq(stringy_array), JSON.parse});

ワンライナーでこれを行うことができますが、それは非常にugいです:

shippingAddresses_uniq = _.map(_.uniq(_.map(_.map(shippingAddresses, function(a){ var o = {}; _.each(Object.keys(shippingAddresses[0]), function(x){o[x] = a[x]}); return o; }), JSON.stringify)), JSON.parse});
1
Matthew Graves

ユーザー入力オブジェクトを確認したい場合は、次の機能を試すことができます。

var uniqueInput = {
                       "country": "UK",
                       "firstname": "Calvin",
                       "lastname": "Borders",
                       "address1": "2201 N Pershing Dr",
                       "address2": "Apt 417",
                       "city": "Arlington",
                       "state": "VA",
                       "Zip": "22201"

                        };

var duplicatedInput = {
                       "country": "US",
                       "firstname": "Kevin",
                       "lastname": "Borders",
                       "address1": "2201 N Pershing Dr",
                       "address2": "Apt 417",
                       "city": "Arlington",
                       "state": "VA",
                       "Zip": "22201"

                        };

var shippingAddresses = [{
                       "firstname": "Kevin",
                       "lastname": "Borders",
                       "address1": "2201 N Pershing Dr",
                       "address2": "Apt 417",
                       "city": "Arlington",
                       "state": "VA",
                       "Zip": "22201",
                       "country": "US"
                        }, {
                            "firstname": "Dan",
                            "lastname": "Hess",
                            "address1": "304 Riversedge Dr",
                            "address2": "",
                            "city": "Saline",
                            "state": "MI",
                            "Zip": "48176",
                            "country": "US"
                        }];

function checkDuplication(checkTarget,source){
    _.each(source,function(obj){
        if(_.isEqual(checkTarget,obj)){ 
            alert("duplicated");
        }
    });
}

そして、異なるパラメーター(uniqueInputとduplicatedInput)でこのチェック関数を呼び出そうとします。配送先住所の複製入力をチェックできると思います。

checkDuplication(uniqueInput,shippingAddresses);
checkDuplication(duplicatedInput,shippingAddresses);

jsfiddle を作成します。あなたはそれを試すことができます。これがあなたのお役に立てば幸いです。

1
Chickenrice

ECMAScript 2015のSet()を使用した基本的な例(ライブラリは不要)

Setオブジェクトを使用すると、任意のタイプの一意の値(プリミティブ値またはオブジェクト参照)を保存できます。反復可能なオブジェクトが渡されると、そのすべての要素が新しいSetに追加されます。ここでは、1つの値を追加します。

// original array with duplicates already present
const numbers = [1, 1, 1, 2, 3, 100]

// Use Set to remove duplicate elements from the array 
// and keep your new addition from causing a duplicate.

// New value (100) is not added since it exists (and array 
// also is de-duped)
console.log(Array.from(new Set([...numbers, 100])))
// [1, 2, 3, 100]

// New, non-existing value (101) is added (and array is de-duped)
console.log(Array.from(new Set([...numbers, 101])))
// [1, 2, 3, 100, 101]
1
Paul Sturm