Array.includes(...) не работает должным образом в машинописном коде

Вот машинописный код, который есть у меня в приложении NexJS:

const holeSet:any[] = [];
.....

let xx = 1, yy = 2;
holeSet.push({x:xx,y:yy});

xx = 3;
yy = 4;
holeSet.push({x:xx,y:yy});

holeSet.map((e) => {
  console.info("element ::"+JSON.stringify(e));
});

const a = 1;
const b = 2;

if (holeSet.includes({x:a.toString(),y:b.toString()}))
  console.info("Value {1;2} FOUND !");

Вот результат, полученный при запуске приведенного выше кода:

элемент ::{"x":1,"y":2} элемент ::{"x":3,"y":4}

Моя проблема в том, что я не знаю, что делаю не так.

Я ожидаю сообщение: Значение {1;2} НАЙДЕНО!

появиться, но этого не происходит. Почему это ?

Я предполагаю, что плохой синтаксис в операторе if ??

Это был мой поиск (с помощью Google, а не функции поиска Stack Overflow)
jcalz 07.08.2024 03:20
^ Спасибо — ТАК поиск действительно нуждается в улучшении…
jsejcksn 07.08.2024 03:23

Array.prototype.includes использует строгое равенство (===), чтобы проверить, существует ли элемент в массиве. Например: const x = {xx: 1, yy: 2}; const y = {xx: 1, yy: 2}; x !== y, потому что они ссылаются на разные объекты в куче памяти. Итак,holeSet.includes({...}) возвращает false. ИспользуйтеholeSet.map(el => JSON.stringify(el)).includes(JSON.stringify({...})) илиholeSet.some(el => el.xx === a && el.yy == = б) или попробуйте lodash библиотеку утилит для более глубокого сравнения. Обратитесь к этому вопросу

Giri 07.08.2024 06:25
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
4
50
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Проблема, с которой вы здесь столкнулись, заключается в том, что при сравнении объектов они сравниваются по ссылке, а не по значению. Таким образом, он пытается проверить, является ли это тем же объектом, которым он никогда не будет. Чтобы преодолеть это, я бы использовал что-то вроде этого:

holeSet.some(e => e.x === a && e.y === b)

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

На самом деле это работает как с: «if (holeSet.some((o) => o.x===j && o.y===i))», так и с: «if (holeSet.some((o) => o.x== j && o.y==i))"

Michel 07.08.2024 11:12
Ответ принят как подходящий

Использование синтаксиса литерала объекта создает новый объект. Например, в коде, который вы показали:

holeSet.push({ x: xx, y: yy });
//           ^^^^^^^^^^^^^^^^

и

if (holeSet.includes({ x: a.toString(), y: b.toString() }))
//                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

…они создают новые, уникальные объекты.

Array.prototype.includes() использует равенство одинакового значения и нуля для сравнения первого аргумента, предоставленного каждому элементу массива (в спецификации это называется алгоритмом SameValueZero). При использовании этого алгоритма два уникальных объекта никогда не будут равны друг другу, поэтому… использование синтаксиса литерала объекта для создания значения первого аргумента при вызове holeSeet.includes всегда будет возвращать false:

holeSet.includes({ x: a.toString(), y: b.toString() })
//               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// Using a unique object for this argument will always return `false`

Вы можете использовать Array.prototype.some(), чтобы определить, имеет ли один из элементов ожидаемую форму, используя функцию, которая сравнивает значения свойств x и y с ожидаемыми значениями:

if (holeSet.some((o) => o.x === a && o.y === b))

Код на игровой площадке TypeScript

В результате условие будет оценено как true, и вы увидите ожидаемое сообщение в консоли.

Другие вопросы по теме