Перевірте, чи існує об'єктне значення в масиві Java-об’єктів, а якщо не додати новий масив до масиву


147

Якщо у мене є такий масив об'єктів:

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

Чи є спосіб провести цикл через масив, щоб перевірити, чи існує певне значення імені користувача, і якщо він нічого не робить, але якщо він не додає новий масив до масиву із вказаним ім'ям користувача (та новим ідентифікатором)?

Дякую!


1
Чи повинні Білл і Тед мати однаковий посвідчення особи?
user2357112 підтримує Monica

Чому є два елементи з однаковим id? Чи можливо, що елементи будуть видалені з цього масиву, чи ми можемо бути впевнені, що новий елемент завжди матиме idрівний arr.length + 1?
raina77ow

Якщо ви не хочете провести цикл через нього, перевірте це запитання щодо розширення прототипу масиву, stackoverflow.com/questions/1988349/… .
Cem Özer

нативні функції повільніше порівняно зі звичайними циклами, і їх підтримка обмежена деякими версіями браузера. перевірити мою відповідь нижче.
Захін

це принципово неправильне питання, оскільки ви можете це зробити, уникаючи використання масивів.
Бекім Бакай

Відповіді:


234

Я припускав, що ids покликані бути унікальними тут. 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
Дякую Енді, це дуже чисте рішення проблеми і працює дуже добре. Я раніше не натрапляв на якийсь метод. Ваше припущення було правильним, моїй приклад ідентифікації був просто друком, я використовував arr.length + 1 для визначення ідентифікатора.
користувач2576960

3
Слідкуйте за тим, щоб IE8 і раніше не підтримували деякі функції.
BetaRide

Чи можна знайдену функцію перетворити на ПЧ? Щось на кшталт: якщо (arr.some (функція (el) {el.Id == someId), і воно поверне або істинне, або хибне, якщо воно існує чи ні?
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

Це гарантуватиме унікальність ідентифікаторів, але зробить цей масив дещо дивним, якщо деякі елементи будуть зняті з його кінця.


Дякую за це Я пішов з рішенням Енді, врешті-решт, тому що це більш стислий спосіб досягти того самого. Я ні в якому разі не видалятиму користувачів, тому ідентифікатори повинні залишатися узгодженими. Перевірка дозволяє користувачам входити, виходити та знову входити, не збільшуючи понаднормовий масив. Щойно для інформації, я використовую цю функцію спільно з passport.js, і мені не вдалося знайти спосіб видалення користувачів з масиву, не граючи з самим паспортним кодом. Це рішення прекрасно працює.
користувач2576960

18

Цей маленький фрагмент працює для мене ..

const arrayOfObject = [{ id: 1, name: 'john' }, {id: 2, name: 'max'}];

const checkUsername = obj => obj.name === 'max';

console.log(arrayOfObject.some(checkUsername))

1
Досить елегантний підхід! - Більше деталей та прикладів з використанням .someзнайденого тут - developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
Джеймс Маріно

10

Я думаю, що це найкоротший шлях вирішення цієї проблеми. Тут я використав функцію стрілки ES6 з .filter, щоб перевірити наявність нещодавно доданого імені користувача.

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


3

Це те , що я зробив на додаток до @ Сагар-gavhane відповідь «s

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)

Привіт, Якщо я знайшов значення, як я можу отримати доступ до ідентифікатора?
Кусал Кітмал

Це зробити дуже просто... 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 }); }
 }

2

Ось ланцюжок методів ES6 з використанням .map()та .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. Якщо його немає, додайте нового користувача

1

Мені подобається відповідь Енді, але ідентифікатор не обов'язково буде унікальним, тому ось що я придумав, щоб створити і унікальний ідентифікатор. Можна перевірити і на jsfiddle . Зауважте, що це arr.length + 1може не гарантувати унікальний ідентифікатор, якщо щось було вилучено раніше.

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

Мені подобається простота в інших відповідях, я щойно опублікував свою, щоб додати чек на унікальний ідентифікатор
Uxonith

Дякую за вашу відповідь Uxonith. На даний момент у мене немає потреби в унікальному ідентифікаторі, тому що я не буду видаляти користувачів з масиву. Я зберігатиму цю резолюцію в задній кишені, якщо виникне потреба. Ще раз
дякую

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)

Другий метод з використанням включає, карту

   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}?
probitaille

1

Припустимо, у нас є масив об'єктів, і ви хочете перевірити, чи визначено значення імені таким чином,

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}?
probitaille

0

Рідні функції масиву іноді в 3X - 5X рази повільніше, ніж у звичайних циклів. Плюс нативні функції не працюватимуть у всіх браузерах, тому є проблеми сумісності.

Мій код:

<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

функція number_present_or_not () { var arr = [ 2,5,9,67,78,8,454,4,6,79,64,688 ] ; var знайдено = 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
Питання про масив об’єктів, і це не спрацює.
Адріан Енрікес

це не правдива відповідь на запитання.
Ахсан Мухтар

ця відповідь не є достатньою вимогою, зазначеною у питанні.
Саван Гадхія
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.