Проверьте, существует ли значение объекта в массиве объектов Javascript, и если нет, добавьте новый объект в массив


161

Если у меня есть следующий массив объектов:

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

Есть ли способ перебрать массив, чтобы проверить, существует ли уже конкретное значение имени пользователя, и если оно ничего не делает, но если оно не добавляет новый объект в массив с указанным именем пользователя (и новым идентификатором)?

Благодарность!


1
У Билла и Теда должно быть одно и то же удостоверение личности?
— user2357112 поддерживает Монику

Почему есть два одинаковых элемента id? Возможно ли, что элементы будут удалены из этого массива, или мы можем быть уверены, что новый элемент всегда будет idравен arr.length + 1?
— raina77ow

Если вы не хотите повторять его, проверьте этот вопрос и ответ для расширения прототипа массива, stackoverflow.com/questions/1988349/… .
— Cem Özer

собственные функции работают медленнее по сравнению с обычными циклами, и их поддержка ограничена некоторыми версиями браузеров. проверьте мой ответ ниже.
— Zaheen

это в корне неверный вопрос, потому что это можно сделать, избегая использования массивов.
— Bekim Bacaj

Ответы:


258

Я предположил, что здесь 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 для определения идентификатора.
— user2576960

3
Помните, что IE8 и более ранние версии не поддерживают некоторые функции.
— BetaRide

Можно ли преобразовать найденную функцию в 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иначе ты ничего не получишь обратно.
— Энди,

30

Проверить существующее имя пользователя довольно просто:

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

Это гарантирует уникальность идентификаторов, но сделает этот массив немного странным, если некоторые элементы будут удалены с его конца.


Спасибо за это. В конце концов, я выбрал решение Энди, потому что это более лаконичный способ добиться того же. Я не буду удалять пользователей ни на каком этапе, поэтому идентификаторы должны оставаться согласованными. Эта проверка позволяет пользователям входить, выходить и снова входить без увеличения массива со временем. Просто для информации я использую эту функцию вместе с паспортом.js, и мне не удалось найти способ удаления пользователей из массива, не играя с самим кодом паспорта. Это решение прекрасно работает.
— user2576960

22

Этот небольшой фрагмент мне подходит ..

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

Ссылка на скрипку


4

Это то , что я сделал в дополнение к @ Сагар-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)

1
Привет! Если я нашел значение, как мне получить доступ к идентификатору?
— 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 }); }
 }

2

попробуй это

первый метод с использованием некоторых

  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

   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

именно то, что я искал, спасибо
— mangrove108

2

Предположим, у нас есть массив объектов, и вы хотите проверить, определено ли значение 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}?
— probitaille

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

Может быть НЕСКОЛЬКО ВОЗМОЖНЫХ СПОСОБОВ проверить, присутствует ли элемент (в вашем случае его объект) в массиве или нет.

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

скажем, вы хотите найти объект с id = 3.

1. find: он ищет элемент в массиве и, если обнаруживает, возвращает этот элемент, иначе return undefined. Он возвращает значение первого элемента в предоставленном массиве, который удовлетворяет предоставленной функции тестирования. Справка

const ObjIdToFind = 5;
const isObjectPresent = arr.find((o) => o.id === ObjIdToFind);
if (!isObjectPresent) {            // As find return object else undefined
  arr.push({ id: arr.length + 1, username: 'Lorem ipsum' });
}

2. фильтр: ищет элементы в массиве и отфильтровывает все элементы, соответствующие условию. Он возвращает новый массив со всеми элементами, и если ни один из них не соответствует условию, то пустой массив. Справка

const ObjIdToFind = 5;
const arrayWithFilterObjects= arr.filter((o) => o.id === ObjIdToFind);
if (!arrayWithFilterObjects.length) {       // As filter return new array
  arr.push({ id: arr.length + 1, username: 'Lorem ipsum' });
}

3. some: метод some () проверяет, присутствует ли хотя бы один элемент в массиве, который проходит проверку, реализованную предоставленной функцией. Он возвращает логическое значение. Справка

const ObjIdToFind = 5;
const isElementPresent = arr.some((o) => o.id === ObjIdToFind);
if (!isElementPresent) {                  // As some return Boolean value
  arr.push({ id: arr.length + 1, username: 'Lorem ipsum' });
}

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 в Lodash можно использовать для этого

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


0

const checkIfElementExists = itemFromArray => itemFromArray . sameKey === outsideObject . samekey ;

if (cartArray.some(checkIfElementExists)) {
    console.log('already exists');
} else {
    alert('does not exists here')
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.