Javascript-форум (https://javascript.ru/forum/)
-   Общие вопросы Javascript (https://javascript.ru/forum/misc/)
-   -   Сравнение массивов (https://javascript.ru/forum/misc/71795-sravnenie-massivov.html)

shoopik 13.12.2017 11:03

Сравнение массивов
 
Здравствуйте, есть два массива, такого вида:
0:
{id: "driver_socket_1", latitude: -11.37080786775757, longitude: -27.69586199177322, iconUrl: "assets/carIcon.png"}
1:
{id: "driver_socket_2", latitude: -28.24136677583389, longitude: -10.25425740195638, iconUrl: "assets/carIcon.png"}
2:
{id: "driver_socket_3", latitude: -40.95439940439371, longitude: -27.673982748204622, iconUrl: "assets/carIcon.png"}
3:
{id: "driver_socket_4", latitude: -22.490445128116, longitude: 9.730743699541932, iconUrl: "assets/carIcon.png"}
4:
{id: "driver_socket_5", latitude: -8.14232867010616, longitude: -5.386359633011523, iconUrl: "assets/carIcon.png"}


Первый массив пустой, второй приходит с сервера. Первый раз когда приходит, присваиваю второй массив к первому. Но вот потом, каждый раз когда приходит, нужно сравнить локальный массив и с сервера, если координаты меняются, нужно изменить именно их. Вопрос как сравнить два массива и если координаты отличаются, поменять их, не обязательно чистый жс, можно лодаш ( jquery не желательно).

До этого просто каждый раз присваивал массив, но это не подходит :)

Nexus 13.12.2017 11:08

shoopik, в цикле пробежаться по массиву не пробовали?
var data,//Текущие данные
	new_data,//Новые данные
	indexed_data={};//id=>item
	
data.forEach(function(item){
	indexed_data[item.id]=item;
});
data=new_data.map(function(item){
	var old_item=indexed_data[item.id]||false;

    if(!old_item)//Is new item
		return item;

	['latitude','longitude'].forEach(function(key){//Update fields
		if(item[key]!=old_item[key])
			old_item[key]=item[key];
	});
	
	return old_item;
});

Alexandroppolus 13.12.2017 12:28

shoopik,
а каждый последующий раз приходит весь массив целиком, или только те пункты, которые поменялись? Могут ли приходить новые пункты, с теми id, которых ещё не было? Могут ли удаляться пункты?

shoopik 13.12.2017 16:08

Цитата:

Сообщение от Alexandroppolus (Сообщение 472808)
shoopik,
а каждый последующий раз приходит весь массив целиком, или только те пункты, которые поменялись? Могут ли приходить новые пункты, с теми id, которых ещё не было? Могут ли удаляться пункты?


каждый раз весь массив целиком, могут приходить те, которых не было, пункты(водители) могут удаляться :)

shoopik 13.12.2017 16:10

Цитата:

Сообщение от Nexus (Сообщение 472804)
shoopik, в цикле пробежаться по массиву не пробовали?
var data,//Текущие данные
	new_data,//Новые данные
	indexed_data={};//id=>item
	
new_data.forEach(function(item){
	indexed_data[item.id]=item;
});
data.map(function(item){
	var new_item=indexed_data[item.id]||item;
	
	['latitude','longitude'].forEach(function(key){
		if(item[key]!=new_item[key])
			item[key]=new_item[key];
	});
	
	return item;
});

спасибо, попробую. вопрос как удалить тех, кого нету)

Nexus 13.12.2017 16:26

shoopik, изменил пост №2

Alexandroppolus 13.12.2017 17:13

Цитата:

Сообщение от shoopik
каждый раз весь массив целиком

тогда почему бы просто не заменять старый на новый?
или тебе надо отследить изменения?

shoopik 13.12.2017 18:29

Цитата:

Сообщение от Nexus (Сообщение 472804)
shoopik, в цикле пробежаться по массиву не пробовали?
data=new_data.map(function(item){
	var old_item=indexed_data[item.id]||false;
        
        if(!old_item)//Is new item
		return item;

	['latitude','longitude'].forEach(function(key){//Update fields
		if(item[key]!=old_item[key])
			old_item[key]=item[key];
	});
	
	return old_item;
});

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

shoopik 13.12.2017 18:31

Цитата:

Сообщение от Alexandroppolus (Сообщение 472834)
тогда почему бы просто не заменять старый на новый?
или тебе надо отследить изменения?

Ну там особенность такая, плавнее изменяется, и окошко над меткой не исчезает, если менять координаты, а не полностью перезаписывать массив.

Dilettante_Pro 13.12.2017 18:48

shoopik,
Цитата:

Сообщение от shoopik
Получается здесь всё равно идёт присвоение

Вы можете по условию if(item[key]!=old_item[key])
делать не только присвоение, а и запустить функцию изменения координат

shoopik 13.12.2017 18:52

Цитата:

Сообщение от Dilettante_Pro (Сообщение 472843)
shoopik,

Вы можете по условию if(item[key]!=old_item[key])
делать не только присвоение, а и запустить функцию изменения координат

но в итоге же создаётся новый объект old_item, и он возвращается, за счет чего идет перерисовка а не присвоение ? не пойму :)

Nexus 13.12.2017 20:03

Цитата:

Сообщение от shoopik
Получается здесь всё равно идёт присвоение, ну т.е. на место старого массива, встаёт копия. Старый же заменяется ?

Старый не заменяется, а изменяется.

shoopik 13.12.2017 20:12

Цитата:

Сообщение от Nexus (Сообщение 472854)
Старый не заменяется, а изменяется.

Где мне можно прочитать объяснение этому ? :)

Nexus 13.12.2017 20:16

shoopik, даже не знаю.
Достаточно просто разобраться, что скрипт делает.
Из массива new_data создается новый массив data, который содержит как новые элементы из массива new_data, так и измененные элементы массива data, если в массивах data и new_data были элементы с одинаковыми id.

shoopik 13.12.2017 20:22

Цитата:

Сообщение от Nexus
создается новый массив data

ага, так всё-таки создаётся ?))

Nexus 14.12.2017 09:27

shoopik, массив фактически другой, но элементы - измененные старые, к которым добавились новые.
Так что можно сказать, что это старый массив, который подвергся изменению.
Какой-то разницы быть не может, если данные хранятся в обычном массиве.

Dilettante_Pro 14.12.2017 10:56

shoopik,
Вы лучше конкретизируйте, какой результат вам нужен в итоге - что, где и по какой причине должно меняться.
Каким образом, на основании чего идет перерисовка?

Alexandroppolus 14.12.2017 11:12

Судя по посту №9 в этом топике, автору нужен "виртуальный ДОМ" или типа того.

shoopik 14.12.2017 17:19

Цитата:

Сообщение от Dilettante_Pro (Сообщение 472891)
shoopik,
Вы лучше конкретизируйте, какой результат вам нужен в итоге - что, где и по какой причине должно меняться.
Каким образом, на основании чего идет перерисовка?

ну т.е. есть объекты в старом массиве типа {id: user1, lat: 55.66}, и если с сервера приходит массив с таким же айди, то в локальном массиве, именно в этом объекте должен поменяться только lat, т.е. не переприсвоение, а именно в том старом объекте, ну и соответственно если с сервера приходит объект с айди которого нет в локальном, он пушиться в локальный, а если в локальном есть лишний объект, он удаляется :)
Зачем это всё ? Т.е. при отрисовке, если подменять массив, то если выбран(выделен, захвачен) какой-то отрисованный объект, он пропадает из выделения, нужно менять именно в старом

Dilettante_Pro 14.12.2017 17:22

shoopik,
Еще раз:
Каким образом, на основании чего идет перерисовка?

Dilettante_Pro 14.12.2017 18:06

Без переформирования, чистое переприсвоение значений при различии.
Различие в первой и последней строках массивов.
С удалением отсутствующих в новом массиве.
С добавлением новых в старый массив.
var data = [{id: "driver_socket_1", latitude: -11.37080786775757, longitude: -27.69586199177322, iconUrl: "assets/carIcon.png"},
{id: "driver_socket_2", latitude: -28.24136677583389, longitude: -10.25425740195638, iconUrl: "assets/carIcon.png"},
{id: "driver_socket_3", latitude: -40.95439940439371, longitude: -27.673982748204622, iconUrl: "assets/carIcon.png"},
{id: "driver_socket_4", latitude: -22.490445128116, longitude: 9.730743699541932, iconUrl: "assets/carIcon.png"},
{id: "driver_socket_5", latitude: -8.14232867010616, longitude: -5.386359633011523, iconUrl: "assets/carIcon.png"}],
    new_data = [{id: "driver_socket_1", latitude: -10.37080786775757, longitude: -28.69586199177322, iconUrl: "assets/carIcon.png"},
{id: "driver_socket_2", latitude: -28.24136677583389, longitude: -10.25425740195638, iconUrl: "assets/carIcon.png"},
{id: "driver_socket_4", latitude: -22.490445128116, longitude: 9.730743699541932, iconUrl: "assets/carIcon.png"},
{id: "driver_socket_5", latitude: -7.14232867010616, longitude: -5.386359633011523, iconUrl: "assets/carIcon.png"},
{id: "driver_socket_6", latitude: -6.14232867010616, longitude: -6.386359633011523, iconUrl: "assets/carIcon.png"}],
	indexed_data={};//id=>item
	
new_data.forEach(function(item){
	indexed_data[item.id]=item;
});
data.forEach(function(item, index){
	var new_item=indexed_data[item.id];
        if(new_item) {
          delete indexed_data[item.id];
        ['latitude','longitude'].forEach(function(key){
		if(item[key]!=new_item[key])
			item[key]=new_item[key];
        });
        } else {
            delete data[index];
        }
 });
for(var key in indexed_data) {
     data.push(indexed_data[key]);
};
alert(JSON.stringify(data));

shoopik 14.12.2017 20:08

Цитата:

Сообщение от Dilettante_Pro (Сообщение 472930)
shoopik,
Еще раз:
Каким образом, на основании чего идет перерисовка?

Сокеты сыпят массивы, потом идет присвоение у меня, типа locaArray = serverArray. Отрисовка, просто берет все объекты в массиве и отрисовывает, один объект - это айдишник, и еще параметры, которые и меняются.

Спасибо, почти то что нужно )) Только, если в new_data есть элементы, которых нету в data, они тоже должны пушиться

Dilettante_Pro 15.12.2017 11:13

shoopik,
Цитата:

Сообщение от shoopik
Отрисовка, просто берет все объекты в массиве и отрисовывает, один объект - это айдишник, и еще параметры, которые и меняются

Не очень понятно, чем старый измененный массив лучше нового, ну да ладно.
Исправил вычеркивание из старого массива и дописал добавление нового в примере пост№21


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