Не работает indexOf для массива объектов
Доброго времени суток!
Столкнулся с проблемкой: формирую массив объектов, при добавлении нового, хочу проверить, есть ли такой объект в массиве. И если есть - то добавлять не надо (т.е. надо добавлять только уникальные объекты). Применяю для проверки метод indexOf(), а он, зараза, всё время -1 выдаёт. Кто тупит: я или он (метод indexOf)? :blink: var mas = []; var obj1 = {a: "a1", b: "b1"}; var obj2 = {a: "a2", b: "b2"}; mas.push(obj1); mas.push(obj2); alert( mas.indexOf({a: "a1", b: "b1"}) ); // всегда -1 П.С. Я так думаю, это связано с тем, что сравниваются не сами объекты, а ссылки на них. |
Keramet,
в строке 6 вы создали новый обьект, который никогда не будет равен другому обьекту.пишите свой фильтр. var mas = []; var obj1 = {a: "a1", b: "b1"}; mas.push(obj1); var obj2 = {a: "a2", b: "b2"}; mas.push(obj2); alert( mas.indexOf(obj1) ); |
рони,
Спасибо. Я правильно понимаю, что indexOf для массива объектов не работает? Наверное, надо every() или forEach() применять, а внутри них определить функцию на проверку наличия нового объекта в массиве... |
Keramet,
можно проверять свойства в every что-то типа if(item.a == "a1" && item.b == "b1" ) return false |
|
Спасибо, вроде разобрался.
|
Мон попробовать проверить по идентичности строкового представления добавляемых объектов
JSON.stringify(obj) |
Как раз сами объекты сравниваются, а они получаются по ссылке. Вы пытаетесь получить индекс объекта, которого де-факто нет в массиве
a = {} b = {} c = {} alert([a, b, c].indexOf(c)) То есть, у вас там просто ахинея вместо кода. конструкция {a: 1} это сахар для new function(){this.a = 1} |
Цитата:
По поводу Вашего кода: у меня не совсем такая ситуация. В вашем примере, вы создали 3 объекта и запихнули их в массив, потом ищите вхождение одного из них. мне надо следующее (если брать ваш код): получаю объект (в вашем случае а), если такой объект (с идентичными значениями свойств) есть в массиве, то я его не добавляю, а если нет такого - тогда добавляем. если у вас в коде добавть строку 5: d = {}; и строке 6 проверить массив с помощью .indexOf(d), то выдаст -1. Хотя такие объекты уже есть. В принципе, я разобрался (спс Рони), просто про ахинею хотелось бы поподробнее ;) |
Keramet,
Ахинея в том, что литералом вы там создаете новый объект, вновь созданный объект не может быть равен ранее созданному, следовательно его не может быть в массиве. ЗЫ Судя по вашим рассуждениям, сомнительно, что вы разобрались в вопросе. |
Цитата:
|
Цитата:
|
Про ахинею вроде разобрались: для вас - ахинея (вы, видимо гуру JS), для меня - процесс обучения.
Теперь про это хотелось бы узнать: Цитата:
|
Keramet,
я Вам уже ответил: в буквальном смысле. Эти 2 конструкции семантически эквивалентны. То есть. Создаем объект, вешаем ему __proto__ = Object.prototype, и сеттим его локальный слот a в значение 1. |
Keramet,
И да, Ваш тон мне не нравится. |
callbackhell,
интересно, но как обычно в целом, не понимаю. |
рони,
Что конкретно? |
callbackhell,
как это поможет сравнить есть похожий обьект в массиве или нет? |
рони,
Что это? Понимание языка? Очевидно поможет. Оно вообще, внезапно, всегда помогает. |
callbackhell,
вариант решения ... var arr = []; function find(arr, obj) { return arr.every(function(el) { return el.a != obj.a || el.b != obj.b }) } var obj = {a: 1, b: 1}; find(arr, obj) && arr.push(obj); obj = {a: 2, b: 1}; find(arr, obj) && arr.push(obj); obj = {a: 1, b: 1}; find(arr, obj) && arr.push(obj); obj = {a: 1, b: 1}; find(arr, obj) && arr.push(obj); obj = {a: 2, b: 2}; find(arr, obj) && arr.push(obj); alert(JSON.stringify(arr)); причём тут прототипы не понимаю |
Цитата:
Но вообще, то что Вы показываете -- это говнопаттерн. Объекты нельзя использовать в качестве хешей, если приходится это делать -- это верный признак говноархитектуры. Но это ладно Цитата:
var arr = [] function find(arr, obj) { return arr.every(function(el) { return el.a != obj.a || el.b != obj.b }) } var obj = Object.create({a: 1, b: 1}); obj.c = 3 find(arr, obj) && arr.push(obj); obj = {a: 2, b: 1}; find(arr, obj) && arr.push(obj); obj = {a: 1, b: 1}; find(arr, obj) && arr.push(obj); obj = {a: 1, b: 1}; find(arr, obj) && arr.push(obj); obj = {a: 2, b: 2}; find(arr, obj) && arr.push(obj); alert(JSON.stringify(arr)) ///[{"c":3},{"a":2,"b":1},{"a":2,"b":2}] |
Цитата:
Цитата:
|
Цитата:
>>почему? Потому что объект имеет другую семантику. Если уж используете таким образом, то хотя бы ограничивайтесь собственными слотами. |
Цитата:
Цитата:
|
рони,
Вам бесполезно что-либо объяснять, Вы совершенно не понимаете программирования, всюду Вам мерещатся кони, заговоры массонов, а JS -- язык с динамическим ООП, не самая простая для понимания вещь. Вам с нуля надо начинать. Ну, или продолжайте быдлокодить на Jquery, как вариант. |
Цитата:
|
Цитата:
|
Цитата:
С Новым годом!!! |
Цитата:
|
Цитата:
var x = {a: 1} есть то же самое что и код var x = new Object(); x.a = 1; конструкция с анонимной функцией дает чуть более длинную цепочку прототипов для объекта - в этом случае x.__proto__ будет прототипом анонимной функции, а x.__proto__.__proto__ равно Object.prototype А для x = {a: 1} уже x.__proto__ равно Object.prototype |
Яростный Меч,
Да, Вы правы, сорь, из головы вылетело, что new создает еще один слой. |
Часовой пояс GMT +3, время: 09:47. |