mirror of
https://github.com/freeCodeCamp/freeCodeCamp.git
synced 2026-05-07 15:03:20 -04:00
refactor(curriculum): drop string-similarity
This commit is contained in:
@@ -65,7 +65,6 @@
|
||||
"@types/debug": "4.1.12",
|
||||
"@types/js-yaml": "4.0.5",
|
||||
"@types/polka": "0.5.7",
|
||||
"@types/string-similarity": "4.0.2",
|
||||
"@typescript/vfs-1.6.1": "npm:@typescript/vfs@1.6.4",
|
||||
"@vitest/ui": "4.0.15",
|
||||
"eslint": "9.39.1",
|
||||
@@ -81,7 +80,6 @@
|
||||
"polka": "0.5.2",
|
||||
"puppeteer": "22.12.1",
|
||||
"sirv": "3.0.2",
|
||||
"string-similarity": "4.0.4",
|
||||
"typescript-5.9.2": "npm:typescript@5.9.2",
|
||||
"vitest": "4.0.15"
|
||||
},
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
import comparison from 'string-similarity';
|
||||
|
||||
/**
|
||||
* Filters the superblocks array to include any superblocks with the specified block.
|
||||
* If no block is provided, returns the original superblocks array.
|
||||
@@ -125,8 +123,74 @@ export const applyFilters: GenericFilterFunction = createFilterPipeline([
|
||||
filterByChallengeId
|
||||
]);
|
||||
|
||||
function normalizeForComparison(value: string): string {
|
||||
return value.toLowerCase().replace(/[^a-z0-9]+/g, '');
|
||||
}
|
||||
|
||||
function createBigrams(value: string): Map<string, number> {
|
||||
const bigrams = new Map<string, number>();
|
||||
|
||||
for (let i = 0; i < value.length - 1; i++) {
|
||||
const bigram = value.slice(i, i + 2);
|
||||
bigrams.set(bigram, (bigrams.get(bigram) ?? 0) + 1);
|
||||
}
|
||||
|
||||
return bigrams;
|
||||
}
|
||||
|
||||
function getSimilarityScore(a: string, b: string): number {
|
||||
if (a === b) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (a.length < 2 || b.length < 2) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
const aBigrams = createBigrams(a);
|
||||
let intersection = 0;
|
||||
|
||||
for (let i = 0; i < b.length - 1; i++) {
|
||||
const bigram = b.slice(i, i + 2);
|
||||
const count = aBigrams.get(bigram);
|
||||
|
||||
if (count) {
|
||||
intersection += 1;
|
||||
aBigrams.set(bigram, count - 1);
|
||||
}
|
||||
}
|
||||
|
||||
return (2 * intersection) / (a.length + b.length - 2);
|
||||
}
|
||||
|
||||
export function closestMatch(target: string, xs: string[]): string {
|
||||
return comparison.findBestMatch(target.toLowerCase(), xs).bestMatch.target;
|
||||
const [firstCandidate, ...rest] = xs;
|
||||
|
||||
if (!firstCandidate) {
|
||||
return target;
|
||||
}
|
||||
|
||||
const normalizedTarget = normalizeForComparison(target);
|
||||
|
||||
let closest = firstCandidate;
|
||||
let closestScore = getSimilarityScore(
|
||||
normalizedTarget,
|
||||
normalizeForComparison(closest)
|
||||
);
|
||||
|
||||
for (const candidate of rest) {
|
||||
const score = getSimilarityScore(
|
||||
normalizedTarget,
|
||||
normalizeForComparison(candidate)
|
||||
);
|
||||
|
||||
if (score > closestScore) {
|
||||
closest = candidate;
|
||||
closestScore = score;
|
||||
}
|
||||
}
|
||||
|
||||
return closest;
|
||||
}
|
||||
|
||||
export function closestFilters(
|
||||
|
||||
19
pnpm-lock.yaml
generated
19
pnpm-lock.yaml
generated
@@ -716,9 +716,6 @@ importers:
|
||||
'@types/polka':
|
||||
specifier: 0.5.7
|
||||
version: 0.5.7
|
||||
'@types/string-similarity':
|
||||
specifier: 4.0.2
|
||||
version: 4.0.2
|
||||
'@typescript/vfs-1.6.1':
|
||||
specifier: npm:@typescript/vfs@1.6.4
|
||||
version: '@typescript/vfs@1.6.4(typescript@5.9.3)'
|
||||
@@ -764,9 +761,6 @@ importers:
|
||||
sirv:
|
||||
specifier: 3.0.2
|
||||
version: 3.0.2
|
||||
string-similarity:
|
||||
specifier: 4.0.4
|
||||
version: 4.0.4
|
||||
typescript-5.9.2:
|
||||
specifier: npm:typescript@5.9.2
|
||||
version: typescript@5.9.2
|
||||
@@ -4911,9 +4905,6 @@ packages:
|
||||
'@types/store@2.0.5':
|
||||
resolution: {integrity: sha512-5NmTKe3GWdOaykzq7no+Ahf6mafJu0oLc9JNhJ3E26+0oFvd6GnksnZQpMXcH526mfG4xDYjFiKzyDL51PzeWQ==}
|
||||
|
||||
'@types/string-similarity@4.0.2':
|
||||
resolution: {integrity: sha512-LkJQ/jsXtCVMK+sKYAmX/8zEq+/46f1PTQw7YtmQwb74jemS1SlNLmARM2Zml9DgdDTWKAtc5L13WorpHPDjDA==}
|
||||
|
||||
'@types/superagent@4.1.19':
|
||||
resolution: {integrity: sha512-McM1mlc7PBZpCaw0fw/36uFqo0YeA6m8JqoyE4OfqXsZCIg0hPP2xdE6FM7r6fdprDZHlJwDpydUj1R++93hCA==}
|
||||
|
||||
@@ -11819,10 +11810,6 @@ packages:
|
||||
resolution: {integrity: sha512-IoHUjcw3Srl8nsPlW04U3qwWPk3oG2ffLM0tN853d/E/JlIvcmZmDY2Kz5HzKp4lEi2T7QD7Zuvjq/1rDw+XcQ==}
|
||||
deprecated: Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.
|
||||
|
||||
string-similarity@4.0.4:
|
||||
resolution: {integrity: sha512-/q/8Q4Bl4ZKAPjj8WerIBJWALKkaPRfrvhfF8k/B23i4nzrlRj2/go1m90In7nG/3XDSbOo0+pu6RvCTM9RGMQ==}
|
||||
deprecated: Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.
|
||||
|
||||
string-width@4.2.3:
|
||||
resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==}
|
||||
engines: {node: '>=8'}
|
||||
@@ -18482,8 +18469,6 @@ snapshots:
|
||||
|
||||
'@types/store@2.0.5': {}
|
||||
|
||||
'@types/string-similarity@4.0.2': {}
|
||||
|
||||
'@types/superagent@4.1.19':
|
||||
dependencies:
|
||||
'@types/cookiejar': 2.1.2
|
||||
@@ -18908,7 +18893,7 @@ snapshots:
|
||||
sirv: 3.0.2
|
||||
tinyglobby: 0.2.15
|
||||
tinyrainbow: 3.0.3
|
||||
vitest: 4.0.15(@opentelemetry/api@1.9.0)(@types/node@25.5.0)(@vitest/ui@4.0.15)(jiti@2.6.1)(jsdom@26.1.0)(msw@2.13.2(@types/node@25.5.0)(typescript@5.9.3))(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.1)
|
||||
vitest: 4.0.15(@opentelemetry/api@1.9.0)(@types/node@24.10.8)(@vitest/ui@4.0.15)(jiti@2.6.1)(jsdom@16.7.0)(msw@2.13.2(@types/node@24.10.8)(typescript@5.9.3))(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.1)
|
||||
|
||||
'@vitest/utils@3.2.4':
|
||||
dependencies:
|
||||
@@ -27133,8 +27118,6 @@ snapshots:
|
||||
lodash.map: 4.6.0
|
||||
lodash.maxby: 4.6.0
|
||||
|
||||
string-similarity@4.0.4: {}
|
||||
|
||||
string-width@4.2.3:
|
||||
dependencies:
|
||||
emoji-regex: 8.0.0
|
||||
|
||||
Reference in New Issue
Block a user