Самый простой способ - сохранить ссылку на объект в переменной.
var map_obj = new Map(),
object = { a: 2, b: 3 };
map_obj.set(object, {'c': 4});
console.log([...map_obj]);
map_obj.delete(object);
console.log([...map_obj]);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Если у вас есть только части объекта, вам нужно найти этот объект путем сравнения объекта.
var map_obj = new Map(),
a = 2, b = 3,
key;
map_obj.set({ a: 2, b: 3 }, {'c': 4});
console.log([...map_obj]);
key = Array.from(map_obj.keys()).find(o => o.a === a && o.b === b);
map_obj.delete(key);
console.log([...map_obj]);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Примечание. Это коммерческий продукт, с которым я связан, но он решает эту проблему.
Я решил эту проблему в нескольких своих приложениях и решил извлечь ее в среду многократного использования. Она называется Superpin и является платформой iOS (коммерческая, лицензия стоит $ 149), которая использует внутреннее дерево для хранения аннотаций и выполняет кластеризацию на основе сетки. Алгоритм довольно быстрый, включенное в пример приложение показывает аэропорты мира (более 30 тыс. Аннотаций +) и работает довольно гладко на iPhone 3G.
Я думаю, что Фото Бриско (ссылка на iTunes) делает это.
Я не думаю, что для этого есть платформа Cocoa Touch.
Доказательство концепции - приложение Offline Maps «Offmaps»;)
Это может быть немного похоже на использование бензопилы для стрижки газона, но вот выдержка из Алгоритмов в ореховой скорлупе.
Создание дерева КейДи...
public class KDFactory {
// Known comparators for partitioning points along dimensional axes.
private static Comparator<IMultiPoint> comparators[ ] ;
// Recursively construct KDTree using median method on input points.
public static KDTree generate (IMultiPoint [ ] points) {
if (points. length == 0) { return null; }
// median will be the root.
int maxD = points[ 0] . dimensionality( );
KDTree tree = new KDTree(maxD) ;
// Make dimensional comparators that compare points by ith dimension
comparators = new Comparator[ maxD+1] ;
for (int i = 1; i <= maxD; i++) {
comparators[ i] = new DimensionalComparator(i) ;
}
tree. setRoot(generate (1, maxD, points, 0, points. length-1) ) ;
return tree;
}
// generate the node for the d-th dimension (1 <= d <= maxD)
// for points[ left, right]
private static DimensionalNode generate (int d, int maxD,
IMultiPoint points[ ] ,
int left, int right) {
// Handle the easy cases first
if (right < left) { return null; }
if (right == left) { return new DimensionalNode (d, points[ left] ) ; }
// Order the array[ left, right] so the mth element will be the median
// and the elements prior to it will all be <=, though they won' t
// necessarily be sorted; similarly, the elements after will all be >=
int m = 1+(right-left) /2;
Selection. select(points, m, left, right, comparators[ d] ) ;
// Median point on this dimension becomes the parent
DimensionalNode dm = new DimensionalNode (d, points[ left+m-1] ) ;
// update to the next dimension, or reset back to 1
if (++d > maxD) { d = 1; }
// recursively compute left and right sub-trees, which translate
// into ' below' and ' above' for n-dimensions.
dm. setBelow(maxD, generate (d, maxD, points, left, left+m-2) ) ;
dm. setAbove(maxD, generate (d, maxD, points, left+m, right) ) ;
return dm;
}
}
Найти ближайших соседей лучше всего: O(log n) worst O(n)
// method in KDTree
public IMultiPoint nearest (IMultiPoint target) {
if (root == null) return null;
// find parent node to which target would have been inserted. This is our
// best shot at locating closest point; compute best distance guess so far
DimensionalNode parent = parent(target) ;
IMultiPoint result = parent. point;
double smallest = target. distance(result) ;
// now start back at the root, and check all rectangles that potentially
// overlap this smallest distance. If better one is found, return it.
double best[ ] = new double[ ] { smallest };
double raw[ ] = target. raw( );
IMultiPoint betterOne = root. nearest (raw, best) ;
if (betterOne ! = null) { return betterOne; }
return result;
}
// method in DimensionalNode. min[ 0] contains best computed shortest distance.
IMultiPoint nearest (double[ ] rawTarget, double min[ ] ) {
// Update minimum if we are closer.
IMultiPoint result = null;
// If shorter, update minimum
double d = shorter(rawTarget, min[ 0] ) ;
if (d >= 0 && d < min[ 0] ) {
min[ 0] = d;
result = point;
}
// determine if we must dive into the subtrees by computing direct
// perpendicular distance to the axis along which node separates
// the plane. If d is smaller than the current smallest distance,
// we could "bleed" over the plane so we must check both.
double dp = Math. abs(coord - rawTarget[ dimension-1] ) ;
IMultiPoint newResult = null;
if (dp < min[ 0] ) {
// must dive into both. Return closest one.
if (above ! = null) {
newResult = above. nearest (rawTarget, min) ;
if (newResult ! = null) { result = newResult; }
}
if (below ! = null) {
newResult = below. nearest(rawTarget, min) ;
if (newResult ! = null) { result = newResult; }
}
} else {
// only need to go in one! Determine which one now.
if (rawTarget[ dimension-1] < coord) {
if (below ! = null) {
newResult = below. nearest (rawTarget, min) ;
}
} else {
if (above ! = null) {
newResult = above. nearest (rawTarget, min) ;
}
}
// Use smaller result, if found.
if (newResult ! = null) { return newResult; }
}
return result;
}
More on KD-дерево в Википедии