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
.
因此问题被简化为我想要找到解决方案的子任务:更新对象数组 - 来自另一个对象数组的标记 - newMarkers。
Thus, need to perform the following manipulation with markers
array:
因此,需要使用markers数组执行以下操作:
- Remove objects from
markers
which are not innewMarkers
(compared by three properties:lat
,lng
,type
). - 从不在newMarkers中的标记中删除对象(通过三个属性进行比较:lat,lng,type)。
- Add objects from
newMarkers
intomarkers
if not exist (compared bylat
,lng
). If marker exist (by two properies:lat
,lng
) is necessary to update it, i.e. to replace by a new marker fromnewMarkers
. - 如果不存在,则将newMarkers中的对象添加到标记中(通过lat,lng进行比较)。如果存在标记(通过两个特性:lat,lng)则需要更新它,即用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'}
2 个解决方案
#1
5
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
.
每个标记和newMarkers中的第一个元素值相等但不是引用,这很重要。因此,您需要更新列表中newMarkers的所有项目,但如果newMarkers中的元素具有与标记中已存在元素相同的所有属性值,则您希望保留原始元素不受标记的影响。
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.
下面的解决方案遍历newMarkers中的所有值,如果标记中的元素具有相同的属性值,则使用标记引用,否则使用newMarkers引用。
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)}`);
});
#2
2
If I'm understanding your problem correctly, you want to reflect changes in newMarkers
in markers
without simply replacing the reference on markers
.
如果我正确理解您的问题,您希望在标记中反映newMarkers中的更改,而不是简单地替换标记上的引用。
// 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));
#1
5
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
.
每个标记和newMarkers中的第一个元素值相等但不是引用,这很重要。因此,您需要更新列表中newMarkers的所有项目,但如果newMarkers中的元素具有与标记中已存在元素相同的所有属性值,则您希望保留原始元素不受标记的影响。
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.
下面的解决方案遍历newMarkers中的所有值,如果标记中的元素具有相同的属性值,则使用标记引用,否则使用newMarkers引用。
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)}`);
});
#2
2
If I'm understanding your problem correctly, you want to reflect changes in newMarkers
in markers
without simply replacing the reference on markers
.
如果我正确理解您的问题,您希望在标记中反映newMarkers中的更改,而不是简单地替换标记上的引用。
// 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));