オブジェクトのJavascript配列内にオブジェクト値が存在するかどうかを確認し、存在しない場合は配列に新しいオブジェクトを追加します


146

オブジェクトの次の配列がある場合:

[ { id: 1, username: 'fred' }, { id: 2, username: 'bill' }, { id: 2, username: 'ted' } ]

特定のユーザー名の値がすでに存在するかどうかを確認するために配列をループする方法はありますか?それが何もしない場合は、そのユーザー名(および新しいID)で新しいオブジェクトを配列に追加しませんか?

ありがとう!


1
ビルとテッドは同じIDを持っているはずですか?
user2357112は

同じ2つの要素があるのはなぜidですか?この配列から要素が削除される可能性はありますか、または新しい要素が常にid等しいことを確認できarr.length + 1ますか?
raina77ow 14

ループしたくない場合は、このQ&Aで配列プロトタイプの拡張について確認してください。stackoverflow.com/ questions / 1988349 /…です。
CemÖzer2014

ネイティブ関数は通常のループと比較して遅く、それらのサポートは一部のブラウザーバージョンに制限されています。以下の私の答えを確認してください。
Zaheen 2017年

これは根本的に間違った質問です。なぜなら、配列の使用を回避することでそれができるからです。
Bekim Bacaj 2017年

回答:


234

idここで、sは一意であることを前提としています。some配列にあるものの存在をチェックするための素晴らしい関数です:

const arr = [{ id: 1, username: 'fred' }, { id: 2, username: 'bill' }, { id: 3, username: 'ted' }];

function add(arr, name) {
  const { length } = arr;
  const id = length + 1;
  const found = arr.some(el => el.username === name);
  if (!found) arr.push({ id, username: name });
  return arr;
}

console.log(add(arr, 'ted'));


1
Andyに感謝します。これは問題に対する非常にクリーンな解決策であり、非常にうまく機能しています。以前は、いくつかの方法に出会ったことがありませんでした。あなたの仮定は正しかった私のIDの例は単なるタイプミスであり、arr.length + 1を使用してIDを決定していました。
user2576960 2014

3
IE8以前は一部の機能をサポートしていないことに注意してください。
BetaRide 2014年

見つかった関数をIFにできますか?次のようなもの:if(arr.some(function(el){el.Id == someId)そして、存在する場合にtrueまたはfalseを返しますか?
stibay

@stibayは、some ありませんブール値を返します。foundいずれかになりますtrueか、falseコールバックの条件が満たされているかどうかによって異なります。
アンディ

1
ああ、確か:if (arr.some(function (el) { return el.Id == someId; })) { // do something }。それを忘れないでください、さもなければreturnあなたは何も取り戻しません。
アンディ

26

既存のユーザー名を確認するのは簡単です。

var arr = [{ id: 1, username: 'fred' }, 
  { id: 2, username: 'bill'}, 
  { id: 3, username: 'ted' }];

function userExists(username) {
  return arr.some(function(el) {
    return el.username === username;
  }); 
}

console.log(userExists('fred')); // true
console.log(userExists('bred')); // false

ただし、この配列に新しいユーザーを追加する必要がある場合の対処方法はそれほど明確ではありません。最も簡単な方法-新しい要素をid等しいにプッシュするだけarray.length + 1です:

function addUser(username) {
  if (userExists(username)) {
    return false; 
  }
  arr.push({ id: arr.length + 1, username: username });
  return true;
}

addUser('fred'); // false
addUser('bred'); // true, user `bred` added

IDの一意性は保証されますが、一部の要素が最後から削除される場合、この配列は少し奇妙に見えます。


これをありがとう。同じことを達成するためのより簡潔な方法であるので、私は最後にアンディの解決策を使いました。私はどの時点でもユーザーを削除しないので、IDの一貫性を保つ必要があります。このチェックにより、ユーザーは、アレイが時間とともに増大することなく、ログイン、ログアウト、および再度ログインできます。参考までに、私はこの関数をpassport.jsと組み合わせて使用​​しており、パスポートコード自体を使用せずに配列からユーザーを削除する方法を見つけることができませんでした。このソリューションはうまく機能します。
user2576960 2014


10

これは、この問題に取り組む最も簡単な方法だと思います。ここでは、.filterでES6の矢印関数を使用して、新しく追加されたユーザー名の存在を確認しています。

var arr = [{
    id: 1,
    username: 'fred'
}, {
    id: 2,
    username: 'bill'
}, {
    id: 3,
    username: 'ted'
}];

function add(name) {
    var id = arr.length + 1;        
            if (arr.filter(item=> item.username == name).length == 0){
            arr.push({ id: id, username: name });
        }
}

add('ted');
console.log(arr);

フィドルへのリンク


3

これは@ sagar-gavhaneの回答に加えて私がやったことです

const newUser = {_id: 4, name: 'Adam'}
const users = [{_id: 1, name: 'Fred'}, {_id: 2, name: 'Ted'}, {_id: 3, 'Bill'}]

const userExists = users.some(user => user.name = newUser.name);
if(userExists) {
    return new Error({error:'User exists'})
}
users.push(newUser)

こんにちは、値を見つけた場合、IDにアクセスするにはどうすればよいですか?
Kusal Kithmal

それを行うのはとても簡単です... if(userExists) { const userId = userExists.id return userId; } ...
マイケル・エニタン

2

受け入れられた回答は、.someの矢印関数を使用して次のように書くこともできます

 function checkAndAdd(name) {
     var id = arr.length + 1;
     var found = arr.some((el) => {
           return el.username === name;
     });
     if (!found) { arr.push({ id: id, username: name }); }
 }

1

Andyの答えは好きですが、IDは必ずしも一意であるとは限りません。そのため、一意のIDを作成するために思いついたのは次のとおりです。jsfiddleでも確認できます。arr.length + 1以前に何かが削除されていた場合、一意のIDが保証されない可能性があることに注意してください。

var array = [ { id: 1, username: 'fred' }, { id: 2, username: 'bill' }, { id: 3, username: 'ted' } ];
var usedname = 'bill';
var newname = 'sam';

// don't add used name
console.log('before usedname: ' + JSON.stringify(array));
tryAdd(usedname, array);
console.log('before newname: ' + JSON.stringify(array));
tryAdd(newname, array);
console.log('after newname: ' + JSON.stringify(array));

function tryAdd(name, array) {
    var found = false;
    var i = 0;
    var maxId = 1;
    for (i in array) {
        // Check max id
        if (maxId <= array[i].id)
            maxId = array[i].id + 1;

        // Don't need to add if we find it
        if (array[i].username === name)
            found = true;
    }

    if (!found)
        array[++i] = { id: maxId, username: name };
}

私は他の回答の単純さが好きです、私は自分のIDのチェックを追加するために投稿しました
Uxonith

あなたの答えUxonithをありがとう。現時点では、アレイからユーザーを削除しないため、一意のIDは必要ありません。必要に応じて、この解決策をバックポケットに保管します。ありがとうございました
user2576960

1

あなたはそれをよりモジュール化するためにあなたの配列をプロトタイプ化することができます、このようなものを試してください

    Array.prototype.hasElement = function(element) {
        var i;
        for (i = 0; i < this.length; i++) {
            if (this[i] === element) {
                return i; //Returns element position, so it exists
            }
        }

        return -1; //The element isn't in your array
    };

そしてあなたはそれを次のように使うことができます:

 yourArray.hasElement(yourArrayElement)

1

何らかの理由で上記の手順を試してみましたが、うまくいかなかったようですが、これは自分の問題に対する私の最終的な解決策であり、これを読んでいる人に役立つかもしれません:

let pst = post.likes.some( (like) => {  //console.log(like.user, req.user.id);
                                     if(like.user.toString() === req.user.id.toString()){
                                         return true
                                     } } )

ここでpost.likesは、投稿を高く評価したユーザーの配列です。


1

これを試して

いくつかを使用する最初の方法

  let arr = [{ id: 1, username: 'fred' }, { id: 2, username: 'bill' }, { id: 3, username: 'ted' }];
    let found = arr.some(ele => ele.username === 'bill');
    console.log(found)

include、mapを使用する2番目の方法

   let arr = [{ id: 1, username: 'fred' }, { id: 2, username: 'bill' }, { id: 3, username: 'ted' }];
    let mapped = arr.map(ele => ele.username);
    let found = mapped.includes('bill');
    console.log(found)

{"name": "test1"、 "age":30}のような2つの属性を持つオブジェクトを比較する場合はどうなりますか?
プロビタイユ

1

オブジェクトの配列があり、nameの値が次のように定義されているかどうかを確認するとします。

let persons = [ {"name" : "test1"},{"name": "test2"}];

if(persons.some(person => person.name == 'test1')) {
    ... here your code in case person.name is defined and available
}

あなたのコードが何をしているかを説明するためにいくつかの文を追加してください。そうすれば、あなたの答えに対するより多くの賛成を得られるようになります。
ファジー分析

{"name": "test1"、 "age":30}のような2つの属性を持つオブジェクトを比較する場合はどうなりますか?
プロビタイユ

1

.map()and を使用したES6メソッドチェーンを次に示します.includes()

const arr = [ { id: 1, username: 'fred' }, { id: 2, username: 'bill' }, { id: 2, username: 'ted' } ]

const checkForUser = (newUsername) => {
      arr.map(user => {
        return user.username
      }).includes(newUsername)
    }

if (!checkForUser('fred')){
  // add fred
}
  1. 既存のユーザーをマッピングして、ユーザー名文字列の配列を作成します。
  2. ユーザー名の配列に新しいユーザー名が含まれているかどうかを確認します
  3. 存在しない場合は、新しいユーザーを追加します

0

配列のネイティブ関数は、通常のループよりも3倍から5倍遅い場合があります。さらに、ネイティブ関数はすべてのブラウザーで機能しないため、互換性の問題があります。

私のコード:

<script>
  var obj = [];

  function checkName(name) {
    // declarations
    var flag = 0;
    var len = obj.length;   
    var i = 0;
    var id = 1;

    // looping array
    for (i; i < len; i++) {
        // if name matches
        if (name == obj[i]['username']) {
            flag = 1;
            break;
        } else {
            // increment the id by 1
            id = id + 1;
        }
    }

    // if flag = 1 then name exits else push in array
    if (flag == 0) {
      // new entry push in array        
      obj.push({'id':id, 'username': name});
    }
  }
  // function end

  checkName('abc');
</script>

これにより、結果をより早く得ることができます。

注:渡されたパラメーターが空であるかどうかはチェックしていません。必要に応じて、チェックしたり、特定の検証用の正規表現を記述したりできます。


0

xorWith ロダッシュでこれを達成するために使用することができます

let objects = [ { id: 1, username: 'fred' }, { id: 2, username: 'bill' }, { id: 2, username: 'ted' } ]
let existingObject = { id: 1, username: 'fred' };
let newObject = { id: 1729, username: 'Ramanujan' }

_.xorWith(objects, [existingObject], _.isEqual)
// returns [ { id: 2, username: 'bill' }, { id: 2, username: 'ted' } ]

_.xorWith(objects, [newObject], _.isEqual)
// returns [ { id: 1, username: 'fred' }, { id: 2, username: 'bill' }, { id: 2, username: 'ted' } ,{ id: 1729, username: 'Ramanujan' } ]


0

function number_present_or_not(){ var arr = [ 2,5,9,67,78,8,454,4,6,79,64,688 ] ; var found = 6; var found_two; (i = 0; i

    }
    if ( found_two == found )
    {
        console.log("number present in the array");
    }
    else
    {
        console.log("number not present in the array");
    }
}

-1

ベストプラクティスは次のとおりです。

var arr = ["a","b","c","d"];
console.log(arr.includes("a")); //---- true;
console.log(arr.includes("k")); //---- false;
console.log(arr.includes("c")); //---- true;

18
問題はオブジェクトの配列であり、これは機能しません。
エイドリアンエンリケス

これは質問に対する正しい答えではありません。
Ahsan Mukhtar、

この回答は、質問で述べられている要件を十分に満たすものではありません。
Savan Gadhiya
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.