From d18b951c67164fdd71c549eae07ab8cc0dd319b6 Mon Sep 17 00:00:00 2001 From: Bryan Housel Date: Thu, 28 Mar 2019 10:03:59 -0400 Subject: [PATCH] Remove lodash flatten and flattenDeep (re: #6087) --- modules/core/validator.js | 58 +++++++++++++++++++++------------------ modules/svg/data.js | 7 ++--- modules/svg/lines.js | 12 +++----- modules/util/array.js | 11 ++++++++ modules/util/index.js | 1 + test/spec/util/array.js | 5 ++++ 6 files changed, 55 insertions(+), 39 deletions(-) diff --git a/modules/core/validator.js b/modules/core/validator.js index def1f3e1e..e79b4d7b4 100644 --- a/modules/core/validator.js +++ b/modules/core/validator.js @@ -1,12 +1,9 @@ -import _flatten from 'lodash-es/flatten'; -import _flattenDeep from 'lodash-es/flattenDeep'; - import { dispatch as d3_dispatch } from 'd3-dispatch'; import { geoExtent } from '../geo'; import { osmEntity } from '../osm'; import { t } from '../util/locale'; -import { utilArrayUniq, utilRebind } from '../util'; +import { utilArrayFlatten, utilRebind } from '../util'; import * as Validations from '../validations/index'; @@ -37,9 +34,9 @@ export function coreValidator(context) { } } - var validationIDsToDisplay = Object.keys(validations).filter(function(rule) { - return rule !== 'maprules'; - }); + var validationIDsToDisplay = Object.keys(validations) + .filter(function(rule) { return rule !== 'maprules'; }); + validationIDsToDisplay.sort(function(rule1, rule2) { return t('issues.' + rule1 + '.title') > t('issues.' + rule2 + '.title'); }); @@ -165,35 +162,44 @@ export function coreValidator(context) { var history = context.history(); var changes = history.changes(); - var entitiesToCheck = changes.created.concat(changes.modified); + var changesToCheck = changes.created.concat(changes.modified); var graph = history.graph(); - _issues = _flatten(changesValidationIDs.map(function(ruleID) { - if (_disabledValidations[ruleID]) { - return []; - } + _issues = utilArrayFlatten(changesValidationIDs.map(function(ruleID) { + if (_disabledValidations[ruleID]) return []; var validation = validations[ruleID]; return validation(changes, context); })); - entitiesToCheck = utilArrayUniq(_flattenDeep(entitiesToCheck.map(function(entity) { + var entitiesToCheck = changesToCheck.reduce(function(acc, entity) { var entities = [entity]; - if (entity.type === 'node') { // validate ways if their nodes have changed - entities = entities.concat(graph.parentWays(entity)); + acc.add(entity); + + if (entity.type === 'node') { + // check parent ways if their nodes have changed + graph.parentWays(entity).forEach(function(parentWay) { + entities.push(parentWay); + acc.add(parentWay); + }); } - entities = entities.map(function(entity) { - if (entity.type !== 'relation') { // validate relations if their geometries have changed - return [entity].concat(graph.parentRelations(entity)); + + entities.forEach(function(entity) { + // check parent relations if their geometries have changed + if (entity.type !== 'relation') { + graph.parentRelations(entity).forEach(function(parentRel) { + acc.add(parentRel); + }); } - return entity; }); - return entities; - }))); + + return acc; + + }, new Set()); + var issuesByID = {}; - for (var entityIndex in entitiesToCheck) { - var entity = entitiesToCheck[entityIndex]; + entitiesToCheck.forEach(function(entity) { var entityIssues = validateEntity(entity); _issuesByEntityID[entity.id] = entityIssues; entityIssues.forEach(function(issue) { @@ -201,7 +207,7 @@ export function coreValidator(context) { // the ID to ensure that there are no duplicate issues. issuesByID[issue.id()] = issue; }); - } + }); for (var issueID in issuesByID) { _issues.push(issuesByID[issueID]); @@ -231,9 +237,7 @@ export function validationIssue(attrs) { // A unique, deterministic string hash. // Issues with identical id values are considered identical. this.id = function() { - if (_id) { - return _id; - } + if (_id) return _id; _id = this.type; diff --git a/modules/svg/data.js b/modules/svg/data.js index ec53f5aef..64a0aacc4 100644 --- a/modules/svg/data.js +++ b/modules/svg/data.js @@ -1,4 +1,3 @@ -import _flatten from 'lodash-es/flatten'; import _throttle from 'lodash-es/throttle'; import { @@ -20,7 +19,7 @@ import { geoExtent, geoPolygonIntersectsPolygon } from '../geo'; import { services } from '../services'; import { svgPath } from './index'; import { utilDetect } from '../util/detect'; -import { utilArrayUnion, utilHashcode } from '../util'; +import { utilArrayFlatten, utilArrayUnion, utilHashcode } from '../util'; var _initialized = false; @@ -516,10 +515,10 @@ export function svgData(projection, context, dispatch) { break; case 'MultiPolygon': - c = _flatten(c); + c = utilArrayFlatten(c); case 'Polygon': case 'MultiLineString': - c = _flatten(c); + c = utilArrayFlatten(c); break; } /* eslint-enable no-fallthrough */ diff --git a/modules/svg/lines.js b/modules/svg/lines.js index 77f28bdf3..b3f9974ed 100644 --- a/modules/svg/lines.js +++ b/modules/svg/lines.js @@ -1,15 +1,11 @@ -import _flatten from 'lodash-es/flatten'; -import _map from 'lodash-es/map'; - import { range as d3_range } from 'd3-array'; import { - svgMarkerSegments, svgPath, svgRelationMemberTags, - svgSegmentWay, svgTagClasses + svgMarkerSegments, svgPath, svgRelationMemberTags, svgSegmentWay, svgTagClasses } from './index'; import { osmEntity, osmOldMultipolygonOuterMember } from '../osm'; -import { utilArrayGroupBy } from '../util'; +import { utilArrayFlatten, utilArrayGroupBy } from '../util'; import { utilDetect } from '../util/detect'; @@ -214,7 +210,7 @@ export function svgLines(projection, context) { return entity.tags.oneway === 'reversible' || entity.tags.oneway === 'alternating'; } ); - onewaydata[k] = _flatten(_map(onewayArr, onewaySegments)); + onewaydata[k] = utilArrayFlatten(onewayArr.map(onewaySegments)); var sidedArr = v.filter(function(d) { return d.isSided(); }); var sidedSegments = svgMarkerSegments( @@ -222,7 +218,7 @@ export function svgLines(projection, context) { function shouldReverse() { return false; }, function bothDirections() { return false; } ); - sideddata[k] = _flatten(_map(sidedArr, sidedSegments)); + sideddata[k] = utilArrayFlatten(sidedArr.map(sidedSegments)); }); diff --git a/modules/util/array.js b/modules/util/array.js index fc189203f..c06e66cde 100644 --- a/modules/util/array.js +++ b/modules/util/array.js @@ -60,6 +60,17 @@ export function utilArrayChunk(a, chunkSize) { } +// Flattens two level array into a single level +// var a = [[1,2,3],[4,5,6],[7]]; +// utilArrayFlatten(a); +// [1,2,3,4,5,6,7]; +export function utilArrayFlatten(a) { + return a.reduce(function(acc, val) { + return acc.concat(val); + }, []); +} + + // Groups the items of the Array according to the given key // `key` can be passed as a property or as a key function // diff --git a/modules/util/index.js b/modules/util/index.js index c7431b503..3ca8460cb 100644 --- a/modules/util/index.js +++ b/modules/util/index.js @@ -1,5 +1,6 @@ export { utilArrayChunk } from './array'; export { utilArrayDifference } from './array'; +export { utilArrayFlatten } from './array'; export { utilArrayGroupBy } from './array'; export { utilArrayIntersection } from './array'; export { utilArrayUnion } from './array'; diff --git a/test/spec/util/array.js b/test/spec/util/array.js index d8e8c2b0c..dcac18b2e 100644 --- a/test/spec/util/array.js +++ b/test/spec/util/array.js @@ -47,6 +47,11 @@ describe('iD.utilArray', function() { expect(iD.utilArrayChunk(a, 4)).to.eql([[1, 2, 3, 4], [5, 6, 7]]); }); + it('utilArrayFlatten returns two level array as single level', function() { + var a = [[1, 2, 3], [4, 5, 6], [7]]; + expect(iD.utilArrayFlatten(a)).to.eql([1, 2, 3, 4, 5, 6, 7]); + }); + describe('utilArrayGroupBy', function() { var pets = [ { type: 'Dog', name: 'Spot' },