Memoize presetCollection.item (it's an Array.find)

Also add tests for `matchAllGeometry`
This commit is contained in:
Bryan Housel
2020-02-05 10:32:20 -05:00
parent 0fe766d9a4
commit e3e7cd3003
4 changed files with 35 additions and 15 deletions

View File

@@ -1,14 +1,23 @@
import { utilArrayUniq, utilEditDistance } from '../util';
//
// `presetCollection` is a wrapper around an `Array` of presets `collection`,
// and decorated with some extra methods for searching and matching geometry
//
export function presetCollection(collection) {
const MAXRESULTS = 50;
let _this = {};
let _memo = {};
_this.collection = collection;
_this.item = (id) => _this.collection.find(d => d.id === id);
_this.item = (id) => {
if (_memo[id]) return _memo[id];
const found = _this.collection.find(d => d.id === id);
if (found) _memo[id] = found;
return found;
};
_this.index = (id) => _this.collection.findIndex(d => d.id === id);
@@ -19,16 +28,15 @@ export function presetCollection(collection) {
};
_this.matchAllGeometry = (geometries) => {
return presetCollection(_this.collection.filter(d => {
if (!d) return false;
return d.matchAllGeometry(geometries);
}));
return presetCollection(
_this.collection.filter(d => d && d.matchAllGeometry(geometries))
);
};
_this.matchAnyGeometry = (geometries) => {
return presetCollection(_this.collection.filter(d => {
return geometries.some(geom => d.matchGeometry(geom));
}));
return presetCollection(
_this.collection.filter(d => geometries.some(geom => d.matchGeometry(geom)))
);
};
_this.fallback = (geometry) => {
@@ -38,7 +46,7 @@ export function presetCollection(collection) {
};
_this.search = (value, geometry, countryCode) => {
if (!value) return this;
if (!value) return _this;
value = value.toLowerCase().trim();

View File

@@ -15,8 +15,10 @@ export { presetField };
export { presetPreset };
// wraps a presetCollection with methods for
// loading new data and returning defaults
//
// `presetIndex` wraps a `presetCollection`
// with methods for loading new data and returning defaults
//
export function presetIndex(context) {
const dispatch = d3_dispatch('recentsChange');
const MAXRECENTS = 30;

View File

@@ -95,9 +95,7 @@ export function presetPreset(presetID, preset, fields, addable, rawPresets) {
_this.matchGeometry = (geom) => _this.geometry.indexOf(geom) >= 0;
_this.matchAllGeometry = (geometries) => {
return geometries.every(geom => _this.geometry.indexOf(geom) >= 0);
};
_this.matchAllGeometry = (geoms) => geoms.every(_this.matchGeometry);
_this.originalScore = _this.matchScore || 1;

View File

@@ -16,6 +16,18 @@ describe('iD.presetPreset', function() {
});
});
describe('#matchAllGeometry', function() {
it('returns false if they don\'t all match', function() {
var preset = iD.presetPreset('test', {geometry: ['line']});
expect(preset.matchAllGeometry(['point','line'])).to.equal(false);
});
it('returns true if they do all match', function() {
var preset = iD.presetPreset('test', {geometry: ['point', 'line']});
expect(preset.matchAllGeometry(['point','line'])).to.equal(true);
});
});
describe('#matchScore', function() {
it('returns -1 if preset does not match tags', function() {
var preset = iD.presetPreset('test', {tags: {foo: 'bar'}});