Javascript-форум (https://javascript.ru/forum/)
-   Общие вопросы Javascript (https://javascript.ru/forum/misc/)
-   -   Не работает indexOf для массива объектов (https://javascript.ru/forum/misc/60444-ne-rabotaet-indexof-dlya-massiva-obektov.html)

Keramet 30.12.2015 12:02

Не работает 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


П.С.
Я так думаю, это связано с тем, что сравниваются не сами объекты, а ссылки на них.

рони 30.12.2015 12:10

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) );

Keramet 30.12.2015 12:16

рони,
Спасибо. Я правильно понимаю, что indexOf для массива объектов не работает?
Наверное, надо every() или forEach() применять, а внутри них определить функцию на проверку наличия нового объекта в массиве...

рони 30.12.2015 12:22

Keramet,
можно проверять свойства в every что-то типа if(item.a == "a1" && item.b == "b1" ) return false

рони 30.12.2015 12:23

Keramet,
https://learn.javascript.ru/object-reference

Keramet 30.12.2015 12:30

Спасибо, вроде разобрался.

Deff 30.12.2015 13:07

Мон попробовать проверить по идентичности строкового представления добавляемых объектов
JSON.stringify(obj)

callbackhell 30.12.2015 18:46

Как раз сами объекты сравниваются, а они получаются по ссылке. Вы пытаетесь получить индекс объекта, которого де-факто нет в массиве
a = {}
b = {}
c = {}
alert([a, b, c].indexOf(c))

То есть, у вас там просто ахинея вместо кода. конструкция {a: 1} это сахар для new function(){this.a = 1}

Keramet 30.12.2015 22:52

Цитата:

Сообщение от callbackhell (Сообщение 402016)
...
То есть, у вас там просто ахинея вместо кода. конструкция {a: 1} это сахар для new function(){this.a = 1}

Простите НЕсведующего: что подразумевается под ахинеей? то, что объект определил с помощью литерала? и что значит: это сахар для new function()...

По поводу Вашего кода: у меня не совсем такая ситуация. В вашем примере, вы создали 3 объекта и запихнули их в массив, потом ищите вхождение одного из них. мне надо следующее (если брать ваш код): получаю объект (в вашем случае а), если такой объект (с идентичными значениями свойств) есть в массиве, то я его не добавляю, а если нет такого - тогда добавляем. если у вас в коде добавть строку 5: d = {}; и строке 6 проверить массив с помощью .indexOf(d), то выдаст -1. Хотя такие объекты уже есть.
В принципе, я разобрался (спс Рони), просто про ахинею хотелось бы поподробнее ;)

callbackhell 30.12.2015 23:15

Keramet,
Ахинея в том, что литералом вы там создаете новый объект, вновь созданный объект не может быть равен ранее созданному, следовательно его не может быть в массиве.

ЗЫ Судя по вашим рассуждениям, сомнительно, что вы разобрались в вопросе.

callbackhell 30.12.2015 23:16

Цитата:

Сообщение от Keramet
и что значит

Значит ровно то, что я написал.

callbackhell 30.12.2015 23:19

Цитата:

Сообщение от Keramet
В принципе, я разобрался (спс Рони), просто про ахинею хотелось бы поподробнее

Кстати, да, Рони Вам сказал то же самое, что и я, я просто не читал тред

Keramet 30.12.2015 23:54

Про ахинею вроде разобрались: для вас - ахинея (вы, видимо гуру JS), для меня - процесс обучения.
Теперь про это хотелось бы узнать:
Цитата:

Сообщение от callbackhell (Сообщение 402016)
конструкция {a: 1} это сахар для new function(){this.a = 1}

как понять это умозаключение? (если, конечно, ГУРУ может столь низко опуститься, чтобы растолковать необученной черни свои постулаты):thanks:

callbackhell 31.12.2015 00:27

Keramet,
я Вам уже ответил: в буквальном смысле. Эти 2 конструкции семантически эквивалентны.

То есть. Создаем объект, вешаем ему __proto__ = Object.prototype, и сеттим его локальный слот a в значение 1.

callbackhell 31.12.2015 00:28

Keramet,
И да, Ваш тон мне не нравится.

рони 31.12.2015 00:34

callbackhell,
интересно, но как обычно в целом, не понимаю.

callbackhell 31.12.2015 00:35

рони,
Что конкретно?

рони 31.12.2015 00:54

callbackhell,
как это поможет сравнить есть похожий обьект в массиве или нет?

callbackhell 31.12.2015 00:55

рони,
Что это? Понимание языка? Очевидно поможет. Оно вообще, внезапно, всегда помогает.

рони 31.12.2015 01:10

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));

причём тут прототипы не понимаю

callbackhell 31.12.2015 01:31

Цитата:

Сообщение от рони
причём тут прототипы не понимаю

А кто сказал, что они тут причем? Перечитайте ветку, Вы вообще о чем то о своем...

Но вообще, то что Вы показываете -- это говнопаттерн. Объекты нельзя использовать в качестве хешей, если приходится это делать -- это верный признак говноархитектуры. Но это ладно
Цитата:

Сообщение от рони
причём тут прототипы не понимаю

Вообще то они к разговору не имеет никакого отношения, почему они вам всюду мерещаться, я не знаю, но в вашем случае они и вправду, как-бы, причем
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}]

рони 31.12.2015 01:36

Цитата:

Сообщение от callbackhell
var obj = Object.create({a: 1, b: 1}); obj.c = 3

это зачем?
Цитата:

Сообщение от callbackhell
Но вообще, то что Вы показываете -- это говнопаттерн. Объекты нельзя использовать в качестве хешей, если приходится это делать -- это верный признак говноархитектуры.

почему?

callbackhell 31.12.2015 01:42

Цитата:

Сообщение от рони
это зачем?

Ну ваша функция принимает произвольный объект, а не заранее подготовленный, правильно? Это просто пример объекта, который может попасть на вход вашей функции.
>>почему?
Потому что объект имеет другую семантику. Если уж используете таким образом, то хотя бы ограничивайтесь собственными слотами.

рони 31.12.2015 01:46

Цитата:

Сообщение от callbackhell
Это просто пример объекта, который может попасть на вход вашей функции.

это вакумный конь вашей фантазии.
Цитата:

Сообщение от callbackhell
Если уж используете таким образом, то хотя бы ограничивайтесь собственными слотами.

я не понимаю что значат эти слова, можно пример или пояснение?

callbackhell 31.12.2015 01:52

рони,
Вам бесполезно что-либо объяснять, Вы совершенно не понимаете программирования, всюду Вам мерещатся кони, заговоры массонов, а JS -- язык с динамическим ООП, не самая простая для понимания вещь. Вам с нуля надо начинать. Ну, или продолжайте быдлокодить на Jquery, как вариант.

рони 31.12.2015 01:56

Цитата:

Сообщение от callbackhell
[{"c":3},{"a":2,"b":1},{"a":2,"b":2}]

функция отработала правильно не смотря на ваши старания, с остальным не хотите не обьясняйте, дело ваше.

callbackhell 31.12.2015 01:58

Цитата:

Сообщение от рони
функция отработала правильно

Так функции всегда отрабатывают "правильно", движок по-другому не может. только не всегда так, как ожидается:)

рони 31.12.2015 02:07

Цитата:

Сообщение от callbackhell
только не всегда так, как ожидается

вода мокрая, вжик сказала пила, когда ей подсунули камень.
С Новым годом!!!

callbackhell 31.12.2015 02:09

Цитата:

Сообщение от рони
С Новым годом!!!

Взаимно:)

Яростный Меч 01.01.2016 21:29

Цитата:

Сообщение от callbackhell
конструкция {a: 1} это сахар для new function(){this.a = 1}

Нет, это не так.
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

callbackhell 02.01.2016 17:22

Яростный Меч,
Да, Вы правы, сорь, из головы вылетело, что new создает еще один слой.


Часовой пояс GMT +3, время: 09:47.