Как я могу проверить равенство объектов в массиве объектов с помощью функции включения массива? - PullRequest
2 голосов
/ 20 июня 2019

Я хочу проверить, есть ли в массиве объект, который в качестве параметра для js включает функцию. Например:

let arr = [
    {'name': 'max', 'age': '20'},
    {'name': 'max', 'age': '21'},
    {'name': 'jane', 'age': '22'}];
console.log(arr.includes({'name': 'max', 'age': '21'})); // FALSE

Это дает мне "ложное" значение. Как я могу проверить равенство объектов в массиве объектов без за цикл цикла

Ответы [ 4 ]

3 голосов
/ 20 июня 2019

Вы можете написать общую функцию, такую ​​как

let matches = flt => x => Object.keys(flt).every(k => flt[k] === x[k]);

, а затем

arr.some(matches({'name': 'max', 'age': '21'}))

Это выполняет поверхностное частичное сравнение. Если вам нужны другие режимы, такие как полное и / или глубокое сравнение, это будет гораздо сложнее реализовать. В этом случае я бы предложил использовать lodash (_.isMatching, _.isEqual).

2 голосов
/ 20 июня 2019

Вот еще один способ достижения того же результата:

Если структура объекта ранее не была известна, т. Е. Когда они динамически меняются, из API или чего-то еще, вы можете использовать следующее решение

let arr = [
    {'name': 'max', 'age': '20'},
    {'name': 'max', 'age': '21'},
    {'name': 'jane', 'age': '22'}
];


let x =   {'name': 'max', 'age': '20'};
let result =arr.map( ele => JSON.stringify(ele)).includes(JSON.stringify(x));
console.log(result)

Приведенное выше решение будет работать и для вложенных объектов.

Примечание Решение имеет два предостережения

  1. Это работает при условии, что порядок ваших ключей остается постоянным по всему массиву также и в объекте x, который вы хотите сравнить
  2. Если в ваших объектах слишком много вложенности, тогда онбудет очень медленноЯ не буду рекомендовать JSON.stringify для тех, кто заботится о производительности.

Редактировать 1

Не работает с круговыми структурами
2 голосов
/ 20 июня 2019

Вот опция, основанная на .some и .entries, чтобы гарантировать, что все переданные пары key-value существуют и сопоставляются внутри целевого массива. Это также игнорирует порядок клавиш и принимает динамический ввод.

В этом примере предполагается, что если предоставлено меньше ключей, проверяются только они. Например, проверка только для {'name': 'max'} вернет true.

let arr = [
    {'name': 'max', 'age': '20'},
    {'name': 'max', 'age': '21'},
    {'name': 'jane', 'age': '22'}];

function includedInArray(lookups, _arr) {
  // Ensure every lookup match.
  return _arr.some(i => {
    // Loop key-value pairs.
    return Object.entries(lookups).every(([key, value]) => {
      return i[key] === value;
    });
  });
};

console.log(includedInArray({
  'name': 'max',
  'age': '21'
 }, arr)); // should return true.
 
 console.log(includedInArray({
  'age': '21',
  'name': 'max'
 }, arr)); // should return true.
 
 console.log(includedInArray({
  'age': '55',
  'name': 'max'
 }, arr)); // should return false.
 
 console.log(includedInArray({
  'name': 'max'
 }, arr)); // should return true.
2 голосов
/ 20 июня 2019

Вы не можете сделать это с includes, потому что вы не обрабатываете проверку на равенство и объекты разные, поэтому ничего не совпадает.

Чтобы делать то, что вы хотите, вы можете использовать some или find!

let arr = [
    {'name': 'max', 'age': '20'},
    {'name': 'max', 'age': '21'},
    {'name': 'jane', 'age': '22'}
];

console.log(arr.some(({name, age}) => name === 'max' && age === '21'));
console.log(!!arr.find(({name, age}) => name === 'max' && age === '21'));

Обратите внимание, что find возвращает объект, я добавил !! для вывода логического результата, но это не обязательно обязательно.

...