【问题标题】:Update objects array from another array从另一个数组更新对象数组
【发布时间】:2017-02-10 01:16:03
【问题描述】:

我的主要任务是更新地图上的标记。

符号

地图上实时显示的标记

var markers = [
  { 'lat':10, 'lng':10, 'type':'simple'},
  { 'lat':20, 'lng':20, 'type':'simple'},
  { 'lat':40, 'lng':40, 'type':'cluster'}
]

应该在地图上的新标记

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'}
]

因此问题被简化为我想找到解决方案的子任务从另一个对象数组 - newMarkers 更新对象数组 - markers

因此,需要对markers数组进行如下操作:

  1. markers 中删除不在newMarkers 中的对象(通过三个属性比较:latlngtype)。
  2. 如果不存在,则将来自newMarkers 的对象添加到markers(与latlng 相比)。如果存在标记(通过两个属性:latlng),则需要对其进行更新,即用来自newMarkers 的新标记替换。

我的解决方案无效,因为它在大量标记上执行了很长时间。

更新后的markers 数组应如下所示:

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'}

【问题讨论】:

  • 您目前的解决方案是什么?
  • 我们对数据了解吗?是否按任何排序顺序?每对 lat/lng 的标记是唯一的吗?
  • 你得到的数组与newMarkers 完全相同,我看不出它有什么不同——你实际上是在删除 newMarkers 数组中没有的任何东西
  • markers = newMarkers,根据您的示例数据集判断。
  • @hackerrdave 我的解决方案,但它在大标记数上运行缓慢 -pastebin.com/NnBU9Fpz

标签: javascript arrays algorithm leaflet lodash


【解决方案1】:

只是为了重新说明问题后在 cmets 中澄清的内容......

markersnewMarkers 中的第一个元素值相等,但引用不相等,这很重要。因此,您希望 newMarkers 中的所有项目在更新后的列表中,但如果 newMarkers 中的元素与 markers 中的现有元素具有所有相同的属性值,那么您希望保留 markers 中的原始元素.

下面的解决方案循环遍历newMarkers 中的所有值,如果markers 中的元素具有相同的属性值,则使用markers 引用,否则使用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】:

    如果我正确理解您的问题,您希望在 markers 中反映 newMarkers 的更改,而不是简单地替换 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));
    

    【讨论】:

      猜你喜欢
      • 2018-06-28
      • 1970-01-01
      • 2021-12-09
      • 1970-01-01
      • 2021-11-17
      • 1970-01-01
      • 2021-10-22
      • 2021-03-30
      • 1970-01-01
      相关资源
      最近更新 更多