Reputation: 1373
My main task is to update the markers on the map.
Notation:
Markers that are displayed in real-time on the map:
var markers = [
{ 'lat':10, 'lng':10, 'type':'simple'},
{ 'lat':20, 'lng':20, 'type':'simple'},
{ 'lat':40, 'lng':40, 'type':'cluster'}
]
New markers which should be on the map:
var newMarkers = [
{ 'lat':10, 'lng':10, 'type':'simple'},
{ 'lat':20, 'lng':20, 'type':'simple'},
{ 'lat':30, 'lng':30, 'type':'simple'},
{ 'lat':50, 'lng':50, 'type':'simple'}
]
Thus the problem is reduced to the subtask which I want to find solution:
update the array of objects - markers
from the another array of objects - newMarkers
.
Thus, need to perform the following manipulation with markers
array:
markers
which are not in newMarkers
(compared by three properties: lat
, lng
, type
). newMarkers
into markers
if not exist (compared by lat
, lng
). If marker exist (by two properies: lat
, lng
) is necessary to update it, i.e. to replace by a new marker from newMarkers
.My solution ineffective since it is because it is performed for a long time on large number of markers.
Updated markers
array should look like:
console.log(markers)
{ 'lat':10, 'lng':10, 'type':'simple'},
{ 'lat':20, 'lng':20, 'type':'simple'},
{ 'lat':30, 'lng':30, 'type':'simple'},
{ 'lat':50, 'lng':50, 'type':'simple'}
Upvotes: 1
Views: 4198
Reputation: 12458
Just to re-state what was clarified in the comments after the question...
The 1st element in each of markers
and newMarkers
are equal by value but not by reference, and that matters. Thus you want all the items from newMarkers
in your updated list, but if an element in newMarkers
has all the same property values as an already existing element in markers
then you want to keep the original element from markers
.
The solution below loops through all the values in newMarkers
and, if an element in markers
has the same property values, the markers
reference is used, otherwise the newMarkers
reference is used.
const markers = [
{ 'lat':10, 'lng':10, 'type':'simple'},
{ 'lat':20, 'lng':20, 'type':'simple'},
{ 'lat':40, 'lng':40, 'type':'cluster'}
];
const newMarkers = [
{ 'lat':10, 'lng':10, 'type':'simple'},
{ 'lat':20, 'lng':20, 'type':'simple'},
{ 'lat':30, 'lng':30, 'type':'simple'},
{ 'lat':50, 'lng':50, 'type':'simple'}
];
const updatedMarkers = newMarkers.map(newMarker =>
markers.reduce((accumulator, origMarker) => (
(
origMarker.lat === newMarker.lat &&
origMarker.lng === newMarker.lng &&
origMarker.type === newMarker.type
) ? origMarker : accumulator
), newMarker)
);
markers.map((marker, idx) => {
console.log(`Element #${idx} from markers is present: ${!!(updatedMarkers.indexOf(marker) + 1)}`);
});
newMarkers.map((marker, idx) => {
console.log(`Element #${idx} from newMarkers is present: ${!!(updatedMarkers.indexOf(marker) + 1)}`);
});
Upvotes: 6
Reputation: 503
If I'm understanding your problem correctly, you want to reflect changes in newMarkers
in markers
without simply replacing the reference on markers
.
// remove (everything in markers that's not in newMarkers) from markers
_.pull(markers, ..._.difference(markers, newMarkers));
// push (everything in newMarkers that's not in markers) to markers
markers.push(..._.difference(newMarkers, markers));
Upvotes: 2