didyoumean2
Advanced tools
Comparing version 1.1.0 to 1.2.0
{ | ||
"name": "didyoumean2", | ||
"version": "1.1.0", | ||
"version": "1.2.0", | ||
"engines": { | ||
@@ -5,0 +5,0 @@ "node": ">=4.2" |
@@ -55,2 +55,9 @@ # didyoumean2 | ||
#### `deburr {boolean}` | ||
- default: `false` | ||
- Converting [Latin-1 Supplement](https://en.wikipedia.org/wiki/Latin-1_Supplement_(Unicode_block)#Character_table) and [Latin Extended-A](https://en.wikipedia.org/wiki/Latin_Extended-A) letters to basic Latin letters and removing [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks) | ||
- Refer to [lodash _.deburr](https://lodash.com/docs#deburr) for how it works | ||
#### `matchPath {string}` | ||
@@ -57,0 +64,0 @@ - default: `''` |
255
src/index.js
'use strict' | ||
const get = require('lodash/get') | ||
const leven = require('leven') | ||
const sample = require('lodash/sample') | ||
const getSimilarity = require('./lib/getSimilarity') | ||
const matchItemProcessor = require('./lib/matchItemProcessor') | ||
const normalizeString = require('./lib/normalizeString') | ||
const resultProcessor = require('./lib/resultProcessor') | ||
const runOptionsSchema = require('./lib/runOptionsSchema') | ||
@@ -36,4 +37,2 @@ const returnTypeEnums = require('./enums/returnTypeEnums') | ||
const caseSensitive = options.caseSensitive | ||
const matchPath = options.matchPath | ||
const returnType = options.returnType | ||
@@ -48,36 +47,15 @@ const threshold = options.threshold | ||
if (!caseSensitive) { | ||
input = input.toLowerCase() | ||
} | ||
const normalizedInput = normalizeString(input, options) | ||
const scoreProcessor = (() => { | ||
const matchItemProcessor = (matchItem) => { | ||
if (matchPath) { | ||
matchItem = get(matchItem, matchPath) | ||
} | ||
if (!caseSensitive) { | ||
matchItem = matchItem.toLowerCase() | ||
} | ||
return matchItem | ||
} | ||
switch (thresholdType) { | ||
case EDIT_DISTANCE: | ||
return (matchItem) => leven(input, matchItemProcessor(matchItem)) | ||
case SIMILARITY: | ||
return (matchItem) => getSimilarity(input, matchItemProcessor(matchItem)) | ||
/* istanbul ignore next */ // handled by simpleSchema | ||
default: | ||
return null | ||
} | ||
})() | ||
let checkIfMatched // Validate if score is matched | ||
let scoreProcessor // Get score | ||
switch (thresholdType) { | ||
case EDIT_DISTANCE: | ||
checkIfMatched = (score) => score <= threshold | ||
scoreProcessor = (matchItem) => { | ||
return leven( | ||
normalizedInput, | ||
matchItemProcessor(matchItem, options) | ||
) | ||
} | ||
break | ||
@@ -87,2 +65,8 @@ | ||
checkIfMatched = (score) => score >= threshold | ||
scoreProcessor = (matchItem) => { | ||
return getSimilarity( | ||
normalizedInput, | ||
matchItemProcessor(matchItem, options) | ||
) | ||
} | ||
break | ||
@@ -94,14 +78,40 @@ | ||
let checkMarginValue // {string} Check for `max` or `min` score value | ||
/*+++++++++++ | ||
+ Matching + | ||
+++++++++++*/ | ||
const matchedIndexes = [] | ||
const matchListLen = matchList.length | ||
switch (returnType) { | ||
case ALL_CLOSEST_MATCHES: | ||
case FIRST_CLOSEST_MATCH: | ||
case RANDOM_CLOSEST_MATCH: | ||
case RANDOM_CLOSEST_MATCH: { | ||
const scores = [] | ||
let marginValue | ||
switch (thresholdType) { | ||
case EDIT_DISTANCE: | ||
checkMarginValue = 'min' | ||
// Process score and save the smallest score | ||
marginValue = Infinity | ||
for (let i = 0; i < matchListLen; i += 1) { | ||
const score = scoreProcessor(matchList[i]) | ||
if (marginValue > score) marginValue = score | ||
scores.push(score) | ||
} | ||
break | ||
case SIMILARITY: | ||
checkMarginValue = 'max' | ||
// Process score and save the largest score | ||
marginValue = 0 | ||
for (let i = 0; i < matchListLen; i += 1) { | ||
const score = scoreProcessor(matchList[i]) | ||
if (marginValue < score) marginValue = score | ||
scores.push(score) | ||
} | ||
break | ||
@@ -112,109 +122,79 @@ | ||
} | ||
break | ||
default: | ||
} | ||
const scoresLen = scores.length | ||
for (let i = 0; i < scoresLen; i += 1) { | ||
const score = scores[i] | ||
/*+++++++++++ | ||
+ Matching + | ||
+++++++++++*/ | ||
const matchedIndexes = [] | ||
const matchListLen = matchList.length | ||
if (returnType === FIRST_MATCH) { | ||
for (let i = 0; i < matchListLen; i += 1) { | ||
const score = scoreProcessor(matchList[i]) | ||
// Return once matched, performance is main target in this returnType | ||
if (checkIfMatched(score)) { | ||
return matchList[i] | ||
if (checkIfMatched(score)) { | ||
// Just save the closest value | ||
if (score === marginValue) { | ||
matchedIndexes.push(i) | ||
} | ||
} | ||
} | ||
} | ||
} else if (returnType === ALL_SORTED_MATCHES) { | ||
const unsortedResults = [] | ||
for (let i = 0; i < matchListLen; i += 1) { | ||
const score = scoreProcessor(matchList[i]) | ||
// save all indexes of matched scores | ||
if (checkIfMatched(score)) { | ||
unsortedResults.push({ | ||
score: score, | ||
i: i | ||
}) | ||
} | ||
break | ||
} | ||
switch (thresholdType) { | ||
case EDIT_DISTANCE: | ||
unsortedResults.sort((a, b) => a.score - b.score) | ||
break | ||
case ALL_MATCHES: | ||
for (let i = 0; i < matchListLen; i += 1) { | ||
const score = scoreProcessor(matchList[i]) | ||
case SIMILARITY: | ||
unsortedResults.sort((a, b) => b.score - a.score) | ||
break | ||
// save all indexes of matched scores | ||
if (checkIfMatched(score)) { | ||
matchedIndexes.push(i) | ||
} | ||
} | ||
/* istanbul ignore next */ // handled by simpleSchema | ||
default: | ||
} | ||
break | ||
for (const unsortedResult of unsortedResults) { | ||
matchedIndexes.push(unsortedResult.i) | ||
} | ||
} else if (checkMarginValue) { | ||
const scores = [] | ||
case ALL_SORTED_MATCHES: { | ||
const unsortedResults = [] | ||
for (let i = 0; i < matchListLen; i += 1) { | ||
const score = scoreProcessor(matchList[i]) | ||
let marginValue | ||
// save all indexes of matched scores | ||
if (checkIfMatched(score)) { | ||
unsortedResults.push({ | ||
score: score, | ||
index: i | ||
}) | ||
} | ||
} | ||
switch (checkMarginValue) { | ||
case 'max': | ||
// Process score and save the largest score | ||
marginValue = 0 | ||
for (let i = 0; i < matchListLen; i += 1) { | ||
const score = scoreProcessor(matchList[i]) | ||
switch (thresholdType) { | ||
case EDIT_DISTANCE: | ||
unsortedResults.sort((a, b) => a.score - b.score) | ||
break | ||
if (marginValue < score) marginValue = score | ||
case SIMILARITY: | ||
unsortedResults.sort((a, b) => b.score - a.score) | ||
break | ||
scores.push(score) | ||
} | ||
break | ||
/* istanbul ignore next */ // handled by simpleSchema | ||
default: | ||
} | ||
case 'min': | ||
// Process score and save the smallest score | ||
marginValue = Infinity | ||
for (let i = 0; i < matchListLen; i += 1) { | ||
const score = scoreProcessor(matchList[i]) | ||
for (const unsortedResult of unsortedResults) { | ||
matchedIndexes.push(unsortedResult.index) | ||
} | ||
if (marginValue > score) marginValue = score | ||
scores.push(score) | ||
} | ||
break | ||
/* istanbul ignore next */ // handled by simpleSchema | ||
default: | ||
break | ||
} | ||
const scoresLen = scores.length | ||
case FIRST_MATCH: | ||
for (let i = 0; i < matchListLen; i += 1) { | ||
const score = scoreProcessor(matchList[i]) | ||
for (let i = 0; i < scoresLen; i += 1) { | ||
const score = scores[i] | ||
if (checkIfMatched(score)) { | ||
// Just save the closest value | ||
if (score === marginValue) { | ||
// Return once matched, performance is main target in this returnType | ||
if (checkIfMatched(score)) { | ||
matchedIndexes.push(i) | ||
break | ||
} | ||
} | ||
} | ||
} else { | ||
for (let i = 0; i < matchListLen; i += 1) { | ||
const score = scoreProcessor(matchList[i]) | ||
// save all indexes of matched scores | ||
if (checkIfMatched(score)) { | ||
matchedIndexes.push(i) | ||
} | ||
} | ||
break | ||
/* istanbul ignore next */ // handled by simpleSchema | ||
default: | ||
} | ||
@@ -227,34 +207,5 @@ | ||
if (!matchedIndexes.length) { | ||
switch (returnType) { | ||
case ALL_CLOSEST_MATCHES: | ||
case ALL_MATCHES: | ||
case ALL_SORTED_MATCHES: | ||
return [] | ||
default: | ||
return null | ||
} | ||
} | ||
switch (returnType) { | ||
case ALL_CLOSEST_MATCHES: | ||
case ALL_MATCHES: | ||
case ALL_SORTED_MATCHES: | ||
return matchedIndexes.map((matchedIndex) => matchList[matchedIndex]) | ||
case FIRST_CLOSEST_MATCH: | ||
return matchList[matchedIndexes[0]] | ||
// case FIRST_MATCH: // It is handled on above | ||
case RANDOM_CLOSEST_MATCH: | ||
return matchList[sample(matchedIndexes)] | ||
/* istanbul ignore next */ // handled by simpleSchema | ||
default: | ||
return null | ||
} | ||
return resultProcessor(matchList, matchedIndexes, returnType) | ||
} | ||
module.exports = didYouMean |
@@ -13,3 +13,2 @@ 'use strict' | ||
if (!a || !b) return 0 | ||
if (a === b) return 1 | ||
@@ -16,0 +15,0 @@ |
@@ -26,2 +26,7 @@ 'use strict' | ||
options.deburr = simpleSchema(options.deburr, { | ||
type: 'boolean', | ||
defaultValue: false | ||
}) | ||
options.matchPath = simpleSchema(options.matchPath, { | ||
@@ -28,0 +33,0 @@ type: 'string', |
'use strict' | ||
const _values = require('lodash/values') | ||
/** | ||
@@ -56,3 +58,3 @@ * A simple schema that check type, fill default value and check enum | ||
if (enums) { | ||
const supportedValues = Object.keys(enums).map((enumKey) => enums[enumKey]) | ||
const supportedValues = _values(enums) | ||
@@ -59,0 +61,0 @@ if (supportedValues.indexOf(value) === -1) { |
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
19104
12
368
117
0