Проверьте, содержит ли массив значение - PullRequest
1 голос
/ 20 марта 2019

У меня есть массив объектов, и мне нужно предотвратить добавление дубликатов объектов в массив. Я попробовал следующий код, чтобы проверить наличие дубликатов:

const array = [{ name: 'John' }];

const newName = {
  name: 'John'
};
console.log(array);
console.log(newName);

if (array.includes(newName)) {
  console.log(newName.name + ' exists');
} else {
  console.log('name does not exist');
}

Консольное ведение журнала сообщает, что объект NewName точно такой же, как массив [0]. Тем не менее,

if(array.includes(newName))

возвращает false.

Что я не так делаю? Я попробовал решения в этом посте, но не повезло:

Как проверить, содержит ли массив объект в JavaScript?

Ответы [ 7 ]

4 голосов
/ 20 марта 2019

Просто вы можете использовать array.some из Документация Array.prototype.some () .

В вашем собственном примере вы можете внести некоторые изменения в вашу программу:

const array = [{ name: "John" }];

  const newName = {
    name: "John"
  };
  console.log(array);
  console.log(newName);

  if (array.some(object => object.name === newName.name)) {
    console.log(newName.name + " exists");
  } else {
    console.log("name does not exist");
  }
3 голосов
/ 20 марта 2019

Вам не хватает только того, что includes проверяет идентичность , когда вы используете его на объекте.newName имеет те же свойства, что и объект в вашем массиве, но это не тот же объект, поскольку два человека по имени Джон - один и тот же человек.Для более наглядного примера запустите {} == {}, и вы получите false.

Чтобы проверить, содержит ли массив объект с таким же именем, вы можете использовать some и передать ему функциюсравнить объект, например

array.some(e => e.name == newName.name)
3 голосов
/ 20 марта 2019

Если name является идентификатором объекта, вы можете использовать функцию some для массива:

const array = [{ name: 'John' }];    
const newName = { name: 'John' };

if (array.some(({name}) => name === newName.name)) {
  console.log(newName.name + ' exists');
} else {
  console.log('name does not exist');
}

Или вы можете проверить, является ли количество свойств одинаковым, а затем для каждого свойства:

const array = [{ name: 'John', age: 33 }, { name: 'John', age: 45 }];    
const newName = { age: 33, name: 'John' };

if (array.some(x => Object.keys(x).length === Object.keys(newName).length && Object.keys(x).every(p => x[p] === newName[p]))) {
  console.log(newName.name + ' exists');
} else {
  console.log('name does not exist');
}
2 голосов
/ 20 марта 2019

используйте это:

var newName = {
 name: 'John'
};
console.log(array);
console.log(newName.name);
var found = array.some(obj => obj.name === newName.name);

if (found) {
 console.log(newName.name + ' exists');
} else {
 console.log('name does not exist');
}
1 голос
/ 20 марта 2019

const array = [{
  name: 'John'
}];

const newName = {
  name: 'John'
};

let resultArr = array.filter((item) => {
  return item.name === newName.name
})

let elementPresentMsg;

if (resultArr.length > 0) {
  elementPresentMsg = newName.name + ' exists';
} else {
  elementPresentMsg = 'name does not exist'
}

document.getElementById('msg').innerHTML = elementPresentMsg;
<html>

<body>

  <p id="msg"></p>

</body>

</html>

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

const array = [{ name: 'John' }];

const newName = {
  name: 'John'
};

let resultArr = array.filter((item) => {
    return item.name === newName.name
})

if (resultArr.length > 0) {
  alert(newName.name + ' exists'); //any way to print result instead of alert
} else {
  alert('name does not exist'); //any way to print result instead of alert
}
0 голосов
/ 20 марта 2019

Это потому, что array[0] не равно newName. В Javascript они указывают на другой элемент. Вы можете попробовать console.log(array[0] == newName), и вы получите false.
Если вы хотите найти дубликаты, вы можете попробовать это так:

if (JSON.stringify(array).indexOf(JSON.stringify(newName)) != -1) {
  console.log('exist')
}
else {
  console.log('not exist')
}
0 голосов
/ 20 марта 2019

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

Но если вы преобразуете объекты в примитивные строки, выполняя JSON.stringify, вы можете использовать Array.includes для глубокого сравнения. Как указывало ttulka , это будет работать только в том случае, если объект для поиска имеет свойства в того же порядка , что и объект, который нужно найти в массиве.

const array = [{ name: 'John', age: 33 }];
const newName = {
  name: 'John',
  age: 33
};
if (array.map(obj => JSON.stringify(obj)).includes(JSON.stringify(newName))) {
  console.log(newName.name + ' exists');
} else {
  console.log('name does not exist');
}

Если вы посмотрите на полифилл Array#includes в MDN, вы увидите, что сравнение происходит с использованием оператора строгого равенства ===:

function sameValueZero(x, y) {
   return x === y || (typeof x === 'number' && typeof y === 'number' && isNaN(x) && isNaN(y));
}

// 7. Repeat, while k < len
while (k < len) {
  // a. Let elementK be the result of ? Get(O, ! ToString(k)).
  // b. If SameValueZero(valueToFind, elementK) is true, return true.
  if (sameValueZero(o[k], valueToFind)) {
      return true;
  }
  // c. Increase k by 1. 
  k++;
}

Поэтому, когда вы сравниваете два разных литерала объекта, используя ===, они не будут равны:

console.log({name :"John"} === {name :"John"});

Но примитивные строки с другой стороны равны, если сравнивать их с ===:

console.log('{name:"John"}' === '{name:"John"}');

Но то же самое не относится к объектам String:

console.log(new String('{name:"John"}') === new String('{name:"John"}'));
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...