Nesne değerinin bir Javascript nesne dizisi içinde olup olmadığını ve diziye yeni bir nesne eklemediğini kontrol edin


147

Aşağıdaki nesne dizisi varsa:

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

Belirli bir kullanıcı adı değerinin zaten var olup olmadığını ve hiçbir şey yapmıyorsa, ancak söz konusu kullanıcı adı (ve yeni kimlik) ile diziye yeni bir nesne eklemezse, dizi arasında döngü yapmanın bir yolu var mı?

Teşekkürler!


1
Bill ve Ted'in aynı kimliğe sahip olması gerekiyor mu?
user2357112 Monica

Neden aynı iki element var id? Öğelerin bu diziden kaldırılması mümkün mü yoksa yeni öğenin her zaman ideşit olacağından emin olabilir miyiz arr.length + 1?
raina77ow

Eğer döngüde dolaşmak istemiyorsanız, dizi prototipini genişletmek için bu Soru ve Cevapları kontrol edin, stackoverflow.com/questions/1988349/… .
Cem Özer

yerel işlevler normal döngülerle karşılaştırıldığında daha yavaştır ve destekleri bazı tarayıcı sürümleriyle sınırlıdır. cevabımı aşağıdan kontrol edin.
Zaheen

bu temelde yanlış bir sorudur çünkü bunu Dizilerin kullanılmasından kaçınarak yapabilirsiniz.
Bekim Bacaj

Yanıtlar:


234

Ben idburada benzersiz olması gerektiğini düşündüm . somedizilerdeki şeylerin varlığını kontrol etmek için harika bir işlevdir:

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
Teşekkürler Andy bu soruna çok temiz bir çözüm ve çok iyi çalışıyor. Daha önce bazı yöntemlerle karşılaşmamıştım. Varsayımınız doğru, kimlik örneğim sadece bir yazım hatasıydı, kimliği belirlemek için arr.length + 1 kullanıyordum.
user2576960

3
IE8 ve önceki sürümlerin bazı işlevleri desteklemediğine dikkat edin.
BetaRide

Bulunan işlev bir EĞER haline getirilebilir mi? Gibi bir şey: if (arr.some (function (el) {el.Id == someId) ve varsa ya da yoksa doğru veya yanlış döndürür?
stibay

@stibay, some yaptığı bir boolean döner. foundya olacak trueya da falsegeri arama koşul yerine olup olmamasına bağlı olarak değişir.
Andy

1
Emin Oh: if (arr.some(function (el) { return el.Id == someId; })) { // do something }. Unutmayın, bir returnşey geri alamazsınız.
Andy

26

Mevcut kullanıcı adını kontrol etmek oldukça önemsiz:

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

Ancak bu diziye yeni bir kullanıcı eklemeniz gerektiğinde ne olacağı belli değil. En kolay çıkış - sadece aşağıdakilere ideşit yeni bir eleman itmek 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

Kimliklerin benzersizliğini garanti eder, ancak bazı öğeler sonundan çıkarılırsa bu dizinin biraz garip görünmesini sağlar.


Bunun için teşekkürler. Sonunda Andy'nin çözümüyle gittim çünkü aynı şeyi başarmanın daha özlü bir yolu. Kullanıcıları hiçbir noktada kaldırmayacağım, bu nedenle kimlikler tutarlı kalmalıdır. Bu denetim, kullanıcıların dizi fazla mesai yapmadan tekrar oturum açmasına, oturumu kapatıp yeniden açmasına olanak tanır. Sadece bilgi için bu fonksiyonu passport.js ile birlikte kullanıyorum ve pasaport kodu ile oynamadan diziden kullanıcıları kaldırmanın bir yolunu bulamadım. Bu çözüm iyi çalışıyor.
user2576960


10

Bence, bu sorunu çözmenin en kısa yolu budur. Burada yeni eklenen kullanıcı adının varlığını kontrol etmek için .filter ile ES6 ok işlevini kullandım.

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

Fiddle Bağlantısı


3

Bu benim ilaveten ne yaptığını @ sagar-gavhane 'ın cevabı

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)

Merhaba, Değeri bulduğumda kimliğe nasıl erişebilirim?
Kusal Kithmal

Bunu yapmak gerçekten çok kolay... if(userExists) { const userId = userExists.id return userId; } ...
Michael Enitan

2

Kabul edilen cevap .some üzerindeki ok işlevi kullanılarak aşağıdaki şekilde de yazılabilir.

 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

İşte .map()ve kullanarak ES6 yöntem zinciri .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. Kullanıcı adı dizeleri dizisi oluşturmak için mevcut kullanıcılar üzerinde eşleme yapın.
  2. Bu kullanıcı adı dizisinin yeni kullanıcı adını içerip içermediğini kontrol edin
  3. Yoksa, yeni kullanıcıyı ekleyin

1

Andy'nin cevabını seviyorum, ancak kimlik mutlaka benzersiz olmayacak, bu yüzden benzersiz bir kimlik oluşturmak için bulduğum şey de bu. Jsfiddle'da da kontrol edilebilir . Daha arr.length + 1önce bir şey kaldırılmışsa benzersiz bir kimliği garanti etmeyebileceğini lütfen unutmayın .

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

Diğer cevaplardaki basitliği beğendim, benzersiz kimliği kontrol etmek için benimkini gönderdim
Uxonith

Cevabınız için teşekkürler Uxonith. Şu anda benzersiz bir kimliğe ihtiyacım yok çünkü kullanıcıları diziden kaldırmayacağım. İhtiyaç olursa bu çözünürlüğü arka cebimde tutacağım. Tekrar teşekkürler
user2576960

1

Dizinizi daha modüler hale getirmek için prototip yazabilir, böyle bir şey deneyebilirsiniz

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

Ve şu şekilde kullanabilirsiniz:

 yourArray.hasElement(yourArrayElement)

1

benim için çalışmıyor dikişler bazı nedenlerden dolayı yukarıdaki adımları denediniz ama bu kendi sorunum için son çözüm sadece belki bu okuma herhangi biri için yararlı oldu:

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

here post.likes bir gönderiyi seven bir kullanıcı dizisidir.


1

bunu dene

bazı kullanarak ilk yöntem

  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)

ikinci yöntemi kullanarak içerir, harita

   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} gibi 2 özniteliğe sahip nesneleri karşılaştırmak istersem ne olur?
probitaille

1

Bir dizi nesnemiz olduğunu ve ad değerinin bu şekilde tanımlanıp tanımlanmadığını kontrol etmek istediğinizi varsayalım,

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

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

Lütfen kodunuzun ne yaptığını açıklamak için birkaç cümle ekleyin, böylece cevabınız için daha fazla oy alabilirsiniz.
Bulanık Analiz

{"Name": "test1", "age": 30} gibi 2 özniteliğe sahip nesneleri karşılaştırmak istersem ne olur?
probitaille

0

Dizinin yerel işlevleri bazen normal döngülerden 3X - 5X kat daha yavaştır. Ayrıca yerel işlevler tüm tarayıcılarda çalışmaz, bu nedenle bir uyumluluk sorunu vardır.

Kodum:

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

Bu şekilde sonucu daha hızlı elde edebilirsiniz.

Not: Geçirilen parametrenin boş olup olmadığını kontrol etmedim, isterseniz bir onay verebilir veya belirli doğrulama için normal bir ifade yazabilirsiniz.


0

xorWith Lodash bunu elde etmek için kullanılabilir

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 bulundu = 6; var bulunan_two; için (i = 0; i

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

-1

En İyi Uygulama böyle.

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
Soru nesnelerin dizisiyle ilgilidir ve bu işe yaramaz.
Adrian Enriquez

bu sorunun cevabı değildir.
Ahsan Mukhtar

bu cevap soruda belirtilen gerekliliği karşılamıyor.
Savan Gadhiya
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.