Array.indexOf в TypeScript/JavaScript

EDIT: хотя этот вопрос отмечен как дублированный этим. Но метод @ssube опрятен и намного умнее.

Я использую Typescript.

Это хорошо работает.

var array1 = [];
array1.push(5);
array1.push(6);
console.log("a", array2.indexOf(6));

Но это плохо работает. Поскольку array2.indexOf возвращает -1, что означает, что он не находит его.

var array2 = [];
array2.push({aa:5,bb:5});
array2.push({aa:6,bb:6});
console.log(array2.indexOf({aa:6,bb:6}));

Похоже, что indexOf не поддерживает Object. Имеет ли TypeScript собственные способы решения этой проблемы? Спасибо.

Ответ 1

Нет. Проблема не в Object, а в том, что вы создаете два разных объекта.

Синтаксис литерала объекта ({foo: 'bar'}) объявляет объект inline. Когда выполняется script, объект создается. Использование этого синтаксиса несколько раз создает несколько объектов.

Вы можете легко проверить это с помощью {foo: 3} === {foo: 3}. Это будет оцениваться как false, но они не являются одним и тем же объектом (ссылка).

Метод indexOf проверяет наличие в массиве объекта, строки, числа и т.д. Вы передаете новый объект, который не находится в массиве.

Если у вас есть ссылка на объект, вы можете использовать его, и indexOf будет работать:

var foo = {aa:5,bb:5}, bar = {aa:6,bb:6};
var array2 = [];
array2.push(foo);
array2.push(bar);
console.log(array2.indexOf(foo));

Поскольку вы ссылаетесь на тот же экземпляр, это напечатает индекс.

Вы также можете использовать filter или find с предикатом для глубокого поиска:

function deepIndexOf(arr, obj) {
  return arr.findIndex(function (cur) {
    return Object.keys(obj).every(function (key) {
      return obj[key] === cur[key];
    });
  });
}

var array2 = [];
array2.push(foo);
array2.push(bar);
console.log(deepIndexOf(array2, foo));

Это не будет возвращаться во вложенные объекты, но выполнит сравнение, которое вы ищете (эквивалентность двух объектов и их непосредственных полей).