Vérifiez si la valeur de l'objet existe dans un tableau d'objets Javascript et sinon ajoutez un nouvel objet au tableau


147

Si j'ai le tableau d'objets suivant:

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

Existe-t-il un moyen de parcourir le tableau pour vérifier si une valeur de nom d'utilisateur particulière existe déjà et si elle ne fait rien, mais si ce n'est pas pour ajouter un nouvel objet au tableau avec ledit nom d'utilisateur (et le nouvel ID)?

Merci!


1
Bill et Ted sont-ils censés avoir la même pièce d'identité?
user2357112 prend en charge Monica le

Pourquoi il y a deux éléments avec le même id? Est-ce possible que des éléments soient supprimés de ce tableau ou pouvons-nous être sûrs que le nouvel élément sera toujours idégal à arr.length + 1?
raina77ow

Si vous ne voulez pas le parcourir en boucle, consultez ces questions et réponses pour l'extension du prototype de tableau, stackoverflow.com/questions/1988349/… .
Cem Özer

Les fonctions natives sont plus lentes que les boucles normales et leur prise en charge est limitée à certaines versions de navigateur. vérifiez ma réponse ci-dessous.
Zaheen

c'est une question fondamentalement fausse car vous pouvez le faire en évitant l'utilisation de tableaux.
Bekim Bacaj

Réponses:


235

J'ai supposé que les ids sont censés être uniques ici. someest une excellente fonction pour vérifier l'existence de choses dans les tableaux:

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
Merci Andy, c'est une solution très propre au problème et fonctionne très bien. Je n'avais jamais rencontré de méthode avant. Votre hypothèse était correcte, mon exemple d'identité n'était qu'une faute de frappe, j'utilisais arr.length + 1 pour déterminer l'ID.
user2576960

3
Attention, IE8 et les versions antérieures ne prennent pas en charge certaines fonctions.
BetaRide

La fonction trouvée peut-elle être transformée en IF? Quelque chose comme: if (arr.some (function (el) {el.Id == someId) et il retournera true ou false s'il existe ou non?
stibay

@stibay, some ne renvoie une valeur booléenne. foundsera soit trueou falseselon que la condition du rappel est remplie.
Andy

1
Oh, bien sûr: if (arr.some(function (el) { return el.Id == someId; })) { // do something }. N'oubliez pas cela returnou vous ne récupérerez rien.
Andy

26

Il est assez simple de vérifier le nom d'utilisateur existant:

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

Mais ce n'est pas si évident que faire lorsque vous devez ajouter un nouvel utilisateur à ce tableau. La solution la plus simple - il suffit de pousser un nouvel élément idégal à 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

Cela garantira l'unicité des ID, mais rendra ce tableau un peu étrange si certains éléments sont retirés de sa fin.


Merci pour cela. J'ai finalement opté pour la solution d'Andy car c'est une manière plus succincte de réaliser la même chose. Je ne supprimerai aucun utilisateur à aucun moment, donc les identifiants doivent rester cohérents. La vérification permet aux utilisateurs de se connecter, de se déconnecter et de se reconnecter sans que la baie ne s'agrandisse. Juste pour info, j'utilise cette fonction en conjonction avec passeport.js et je n'ai pas été en mesure de trouver un moyen de supprimer des utilisateurs du tableau sans jouer avec le code de passeport lui-même. Cette solution fonctionne bien.
user2576960


10

Je pense que c'est le moyen le plus court de résoudre ce problème. Ici, j'ai utilisé la fonction de flèche ES6 avec .filter pour vérifier l'existence d'un nom d'utilisateur nouvellement ajouté.

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

Lien vers Fiddle


3

C'est ce que j'ai fait en plus de la réponse de @ 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)

Salut, Si j'ai trouvé la valeur, comment puis-je accéder à l'identifiant?
Kusal Kithmal

C'est vraiment simple de faire ça... if(userExists) { const userId = userExists.id return userId; } ...
Michael Enitan

2

La réponse acceptée peut également être écrite de la manière suivante en utilisant la fonction de flèche sur .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 }); }
 }

2

Voici une chaîne de méthodes ES6 utilisant .map()et .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. Mappez sur les utilisateurs existants pour créer un tableau de chaînes de nom d'utilisateur.
  2. Vérifiez si ce tableau de noms d'utilisateur inclut le nouveau nom d'utilisateur
  3. S'il n'est pas présent, ajoutez le nouvel utilisateur

1

J'aime la réponse d'Andy, mais l'identifiant ne sera pas nécessairement unique, alors voici ce que j'ai proposé pour créer un identifiant unique également. Peut également être vérifié sur jsfiddle . Veuillez noter que cela arr.length + 1peut très bien ne pas garantir un identifiant unique si quelque chose avait été supprimé précédemment.

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

J'aime la simplicité dans les autres réponses, je viens de poster la mienne pour ajouter le chèque d'identité unique
Uxonith

Merci pour votre réponse Uxonith. Pour le moment, je n'ai pas besoin d'identifiant unique car je ne supprimerai pas les utilisateurs du tableau. Je garderai cette résolution dans ma poche arrière en cas de besoin. Merci encore
user2576960

1

Vous pouvez prototyper votre baie pour la rendre plus modulaire, essayez quelque chose comme ça

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

Et vous pouvez l'utiliser comme:

 yourArray.hasElement(yourArrayElement)

1

J'ai essayé les étapes ci-dessus pour une raison quelconque, cela ne semble pas fonctionner pour moi, mais c'était ma solution finale à mon propre problème, peut-être utile à quiconque lit ceci:

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

ici post.likes est un tableau d'utilisateurs qui ont aimé un message.


1

essaye ça

première méthode utilisant certains

  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)

deuxième méthode utilisant inclut, 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)

Que faire si je veux comparer des objets avec 2 attributs comme {"name": "test1", "age": 30}?
probitaille

1

Supposons que nous ayons un tableau d'objets et que vous vouliez vérifier si la valeur du nom est définie comme ceci,

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

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

Veuillez ajouter quelques phrases pour expliquer ce que fait votre code, afin que vous puissiez obtenir plus de votes positifs pour votre réponse.
Analyse floue le

Que faire si je veux comparer des objets avec 2 attributs comme {"name": "test1", "age": 30}?
probitaille

0

Les fonctions natives du tableau sont parfois 3 à 5 fois plus lentes que les boucles normales. De plus, les fonctions natives ne fonctionneront pas dans tous les navigateurs, il y a donc des problèmes de compatibilité.

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

De cette façon, vous pouvez obtenir un résultat plus rapidement.

Remarque: je n'ai pas vérifié si le paramètre passé est vide ou non, si vous le souhaitez, vous pouvez le cocher ou écrire une expression régulière pour une validation particulière.


0

xorWith à Lodash peut être utilisé pour y parvenir

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; pour (i = 0; i

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

-1

La meilleure pratique est comme ça.

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
La question concerne le tableau des objets et cela ne fonctionnera pas.
Adrian Enriquez

ce n'est pas la bonne réponse à la question.
Ahsan Mukhtar

cette réponse ne suffit pas à l'exigence mentionnée dans la question.
Savan Gadhiya le
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.