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

161

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

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

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

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

user2576960
источник
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
Спасибо за ответ 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 - это множество пользователей, которым понравился пост.

NETFLEXX Джозеф
источник
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' });
}
De C
источник
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' } ]
sudo бангбэнг
источник
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");
    }
}
Наккиран 8797
источник
0

Вы также можете попробовать это

 const addUser = (name) => {
    if (arr.filter(a => a.name == name).length <= 0)
        arr.push({
            id: arr.length + 1,
            name: name
        })
}
addUser('Fred')
Шибин Марьян Стэнли
источник
0

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

if (cartArray.some(checkIfElementExists)) {
    console.log('already exists');
} else {
    alert('does not exists here')
Леон Декам
источник