Überprüfen Sie, ob ein Objektwert in einem Javascript-Array von Objekten vorhanden ist, und fügen Sie dem Array ein neues Objekt hinzu


146

Wenn ich das folgende Array von Objekten habe:

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

Gibt es eine Möglichkeit, das Array zu durchlaufen, um zu überprüfen, ob ein bestimmter Benutzername bereits vorhanden ist und ob er nichts tut, aber dem Array kein neues Objekt mit diesem Benutzernamen (und dieser neuen ID) hinzuzufügen?

Vielen Dank!


1
Sollen Bill und Ted den gleichen Ausweis haben?
user2357112 unterstützt Monica

Warum gibt es zwei Elemente mit demselben id? Ist es möglich, dass Elemente aus diesem Array entfernt werden, oder können wir sicher sein, dass das neue Element immer idgleich ist arr.length + 1?
raina77ow

Wenn Sie keine Schleife durchführen möchten, lesen Sie diese Fragen und Antworten , um den Array-Prototyp zu erweitern: stackoverflow.com/questions/1988349/… .
Cem Özer

native Funktionen sind im Vergleich zu normalen Schleifen langsamer und ihre Unterstützung ist auf einige Browserversionen beschränkt. Überprüfen Sie meine Antwort unten.
Zaheen

Dies ist eine grundsätzlich falsche Frage, da Sie dies tun können, indem Sie die Verwendung von Arrays vermeiden.
Bekim Bacaj

Antworten:


234

Ich habe angenommen, dass ids hier einzigartig sein sollen. someist eine großartige Funktion zum Überprüfen der Existenz von Dingen in Arrays:

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
Danke Andy, dies ist eine sehr saubere Lösung für das Problem und funktioniert sehr gut. Ich war noch nie auf eine Methode gestoßen. Ihre Annahme war richtig. Mein ID-Beispiel war nur ein Tippfehler. Ich habe arr.length + 1 verwendet, um die ID zu bestimmen.
user2576960

3
Beachten Sie, dass IE8 und frühere Versionen die Funktion some nicht unterstützen.
BetaRide

Kann die gefundene Funktion in eine IF umgewandelt werden? Etwas wie: if (arr.some (function (el) {el.Id == someId) und es wird entweder true oder false zurückgeben, ob es existiert oder nicht?
stibay

@stibay, some gibt einen Booleschen Wert zurück. foundwird entweder trueoder falseabhängig davon, ob die Bedingung im Rückruf erfüllt ist.
Andy

1
Oh, sicher : if (arr.some(function (el) { return el.Id == someId; })) { // do something }. Vergiss das nicht returnoder du bekommst nichts zurück.
Andy

25

Es ist ziemlich trivial, nach dem vorhandenen Benutzernamen zu suchen:

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

Es ist jedoch nicht so offensichtlich, was zu tun ist, wenn Sie diesem Array einen neuen Benutzer hinzufügen müssen. Der einfachste Ausweg - einfach ein neues Element mit idgleichem Druck drücken 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

Dies garantiert die Eindeutigkeit der IDs, lässt dieses Array jedoch etwas seltsam aussehen, wenn einige Elemente von seinem Ende entfernt werden.


Danke dafür. Am Ende habe ich mich für Andys Lösung entschieden, weil es eine prägnantere Möglichkeit ist, dasselbe zu erreichen. Ich werde zu keinem Zeitpunkt Benutzer entfernen, daher sollten die IDs konsistent bleiben. Mit dieser Prüfung können sich Benutzer anmelden, abmelden und wieder anmelden, ohne dass das Array über die Zeit hinaus wächst. Nur zur Information, ich verwende diese Funktion in Verbindung mit passport.js und konnte keine Möglichkeit finden, Benutzer aus dem Array zu entfernen, ohne mit dem Passcode selbst zu spielen. Diese Lösung funktioniert gut.
user2576960


10

Ich denke, dies ist der kürzeste Weg, um dieses Problem anzugehen. Hier habe ich die ES6-Pfeilfunktion mit .filter verwendet, um das Vorhandensein eines neu hinzugefügten Benutzernamens zu überprüfen.

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);

Link zu Fiddle


3

Dies habe ich zusätzlich zu der Antwort von @ sagar-gavhane getan

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)

Hallo, wenn ich den Wert gefunden habe, wie kann ich auf die ID zugreifen?
Kusal Kithmal

Es ist wirklich einfach, das zu tun... if(userExists) { const userId = userExists.id return userId; } ...
Michael Enitan

2

Akzeptierte Antworten können auch folgendermaßen mit der Pfeilfunktion auf .some geschrieben werden

 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

Ich mag Andys Antwort, aber die ID wird nicht unbedingt eindeutig sein. Deshalb habe ich mir Folgendes ausgedacht, um auch eine eindeutige ID zu erstellen. Kann auch bei jsfiddle überprüft werden. Bitte beachten Sie, dass dies arr.length + 1möglicherweise keine eindeutige ID garantiert, wenn zuvor etwas entfernt wurde.

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 };
}

Ich mag die Einfachheit in den anderen Antworten, ich habe gerade meine gepostet, um den Scheck für eindeutige ID
hinzuzufügen

Danke für deine Antwort Uxonith. Im Moment benötige ich keine eindeutige ID, da ich keine Benutzer aus dem Array entfernen werde. Ich werde diese Auflösung in meiner Gesäßtasche aufbewahren, falls dies erforderlich sein sollte.
Nochmals vielen

1

Sie können Ihr Array als Prototyp erstellen, um es modularer zu gestalten. Probieren Sie Folgendes aus

    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
    };

Und Sie können es verwenden als:

 yourArray.hasElement(yourArrayElement)

1

Ich habe die obigen Schritte aus irgendeinem Grund ausprobiert, es scheint nicht für mich zu funktionieren, aber dies war meine endgültige Lösung für mein eigenes Problem, nur vielleicht hilfreich für jemanden, der dies liest:

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

hier post.likes ist eine Reihe von Benutzern, denen ein Beitrag gefallen hat.


1

Versuche dies

erste Methode mit einigen

  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)

zweite Methode mit Includes, Map

   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)

Was ist, wenn ich Objekte mit 2 Attributen wie {"name": "test1", "age": 30} vergleichen möchte?
Probitaille

1

Nehmen wir an, wir haben ein Array von Objekten und Sie möchten überprüfen, ob der Wert des Namens wie folgt definiert ist.

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

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

Bitte fügen Sie ein paar Sätze hinzu, um zu erklären, was Ihr Code tut, damit Sie mehr positive Stimmen für Ihre Antwort erhalten.
Fuzzy-Analyse

Was ist, wenn ich Objekte mit 2 Attributen wie {"name": "test1", "age": 30} vergleichen möchte?
Probitaille

1

Hier ist eine ES6-Methodenkette mit .map()und .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. Ordnen Sie vorhandene Benutzer zu, um ein Array von Benutzernamenzeichenfolgen zu erstellen.
  2. Überprüfen Sie, ob dieses Array von Benutzernamen den neuen Benutzernamen enthält
  3. Wenn es nicht vorhanden ist, fügen Sie den neuen Benutzer hinzu

0

Native Funktionen des Arrays sind manchmal 3- bis 5-mal langsamer als normale Schleifen. Außerdem funktionieren native Funktionen nicht in allen Browsern, sodass Kompatibilitätsprobleme auftreten.

Mein Code:

<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>

Auf diese Weise können Sie schneller Ergebnisse erzielen.

Hinweis: Ich habe nicht überprüft, ob der übergebene Parameter leer ist oder nicht. Wenn Sie möchten, können Sie ihn überprüfen oder einen regulären Ausdruck für eine bestimmte Validierung schreiben.


0

xorWith in Lodash kann verwendet werden, um dies zu erreichen

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

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

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

-1

Die Best Practice ist so.

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
Die Frage bezieht sich auf eine Reihe von Objekten und dies wird nicht funktionieren.
Adrian Enriquez

Dies ist nicht die richtige Antwort auf die Frage.
Ahsan Mukhtar

Diese Antwort reicht nicht aus, um die in der Frage genannten Anforderungen zu erfüllen.
Savan Gadhiya vor
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.