{"id":37055828,"url":"https://github.com/andrewjsaid/levenshtypo","last_synced_at":"2026-01-14T06:18:10.926Z","repository":{"id":250959907,"uuid":"835968102","full_name":"andrewjsaid/levenshtypo","owner":"andrewjsaid","description":"A fuzzy string dictionary based on Levenshtein automata","archived":false,"fork":false,"pushed_at":"2025-07-12T15:37:26.000Z","size":1759,"stargazers_count":6,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-10-25T01:05:14.298Z","etag":null,"topics":["dotnet","edit-distance","fuzzy-string","fuzzy-string-matching","levenshtein","levenshtein-automata","levenshtein-string-distance","optimal-string-alignment","restricted-edit","string-distance","string-matching"],"latest_commit_sha":null,"homepage":"","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/andrewjsaid.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2024-07-30T22:26:42.000Z","updated_at":"2025-10-07T10:08:49.000Z","dependencies_parsed_at":"2024-07-31T02:59:02.189Z","dependency_job_id":"8b2615fd-1a8e-4bc8-b4c2-acca6855d9e2","html_url":"https://github.com/andrewjsaid/levenshtypo","commit_stats":null,"previous_names":["andrewjsaid/levenshtypo"],"tags_count":9,"template":false,"template_full_name":null,"purl":"pkg:github/andrewjsaid/levenshtypo","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/andrewjsaid%2Flevenshtypo","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/andrewjsaid%2Flevenshtypo/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/andrewjsaid%2Flevenshtypo/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/andrewjsaid%2Flevenshtypo/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/andrewjsaid","download_url":"https://codeload.github.com/andrewjsaid/levenshtypo/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/andrewjsaid%2Flevenshtypo/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28412194,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-14T05:26:33.345Z","status":"ssl_error","status_checked_at":"2026-01-14T05:21:57.251Z","response_time":107,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["dotnet","edit-distance","fuzzy-string","fuzzy-string-matching","levenshtein","levenshtein-automata","levenshtein-string-distance","optimal-string-alignment","restricted-edit","string-distance","string-matching"],"created_at":"2026-01-14T06:18:10.345Z","updated_at":"2026-01-14T06:18:10.912Z","avatar_url":"https://github.com/andrewjsaid.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"﻿# 🔍 Levenshtypo\n\n\u003e Fast, typo-tolerant string lookup for your .NET apps – powered by Levenshtein Automata + Trie magic.\n\n**Levenshtypo** is a high-performance fuzzy matching library that helps you find strings _even when your users mistype them_. Whether you're building search, suggestions, command matchers, or text correction tools, Levenshtypo lets you query massive datasets with typo tolerance and blazingly fast response times.\n\n---\n\n## 🚀 Features\n\n- ⚡️ **Fast fuzzy lookup** over large datasets\n- 📚 Backed by a Trie for fast prefix traversal\n- 🧠 Uses [Levenshtein Distance](https://en.wikipedia.org/wiki/Levenshtein_distance) for string matching\n- 🎯 Also supports **restricted edit distance** (insertions, deletions, substitutions + transpositions)\n- 🏗️ Fully exposed **Levenshtein Automata** for custom workflows\n- 🧪 Minimal allocations and branchy hot paths tuned for speed\n\n---\n\n## 💡 Why Use Levenshtypo?\n\nTraditional string matching fails when:\n\n- Your users make typos (`\"git cmomit\"`)\n- Input comes from noisy sources (voice input, OCR)\n- You want a UX that _feels smart_, not frustrating\n\nInstead of `dictionary[\"cmomit\"]` you can do `leveshtrie.Search(\"cmomit\", maxEditDistance: 1)`.\n\n---\n\n## 🧪 Basic Usage\n\n```csharp\nusing Levenshtypo;\n\nvar matcher = Levenshtrie.CreateStrings([\"docker\", \"doctor\", \"rocket\", \"locker\"]);\n\nforeach (var match in matcher.Search(\"docer\", 2))\n{\n    Console.WriteLine($\"{match.Result} (distance {match.Distance})\");\n}\n\n// docker(distance 1)\n// doctor(distance 2)\n// locker(distance 2)\n```\n\n### 🧠 Under the Hood\n\n- The dataset is loaded into a [Trie](https://en.wikipedia.org/wiki/Trie).\n- A Levenshtein automaton is built on the fly from your query.\n- The trie is traversed with the automaton to **prune irrelevant branches early**, yielding matches quickly.\n\n---\n\n## 🔨 Installation\n\n📦 Available on NuGet:\n\n```\nInstall-Package Levenshtypo\n```\n\nOr via CLI:\n\n```bash\ndotnet add package Levenshtypo\n```\n\n[![Automated Tests](https://github.com/andrewjsaid/levenshtypo/actions/workflows/tests.yml/badge.svg)](https://github.com/andrewjsaid/levenshtypo/actions/workflows/tests.yml)\n\n[![AOT Compatible](https://github.com/andrewjsaid/levenshtypo/actions/workflows/aot.yml/badge.svg)](https://github.com/andrewjsaid/levenshtypo/actions/workflows/aot.yml)\n\n---\n\n## ⚙️ Automaton-Only Mode\n\nNeed raw speed and full control?\n\n```csharp\nvar automaton = LevenshtomatonFactory.Instance.Construct(\n        \"docker\",\n        maxEditDistance: 2,\n        metric: LevenshtypoMetric.RestrictedEdit);\n\nforeach (var word in english)\n{\n    if (automaton.Matches(word))\n    {\n        Console.WriteLine(word);\n    }\n}\n```\n\n☝️ Over 3000x faster than using `if(LevenshteinDistance(word, \"docker\") \u003c= 2)`\n\nYou can hook into the automaton layer directly for:\n\n- Custom indexing\n- Building autocomplete engines\n- Approximate dictionary search\n\n---\n\n## 🧠 Performance\n\nLevenshtypo is written with performance at the forefront of all decisions.\n\n\u003e Practical Example: Matching against **450,000+ words** (Edit Distance = 1) is typically less than **0.02 ms** compared to 73 ms with a for-loop.\n\nIf the following benchmarks don't impress you, nothing will!\n\n\u003cdetails\u003e\n\u003csummary\u003eSearch all English Language with a fuzzy key\u003c/summary\u003e\n\n- **Naive**: Compute Levenshtein Distance against all words.\n- **Levenshtypo_All**: This library, with all results buffered into an array.\n- **Levenshtypo_Lazy**: This library, with lazy evaluation (`IEnumerable`).\n- **Levenshtypo_Any**: This library, with lazy evaluation (`IEnumerable`), stopping at the first result.\n- **Dictionary**: .NET Dictionary which only works for distance of 0.\n\n| Method                     |              Mean | Allocated |\n| -------------------------- | ----------------: | --------: |\n| Distance0_Levenshtypo_All  |        361.444 ns |     240 B |\n| Distance0_Levenshtypo_Lazy |        975.169 ns |     480 B |\n| Distance0_Levenshtypo_Any  |        614.947 ns |     480 B |\n| Distance0_Dictionary       |          9.128 ns |         - |\n| Distance0_Naive            |    813,419.616 ns |      89 B |\n| Distance1_Levenshtypo_All  |     19,008.096 ns |     536 B |\n| Distance1_Levenshtypo_Lazy |     38,615.868 ns |     480 B |\n| Distance1_Levenshtypo_Any  |     25,805.258 ns |     480 B |\n| Distance1_Naive            | 73,459,775.661 ns |     193 B |\n| Distance2_Levenshtypo_All  |    276,157.020 ns |    2600 B |\n| Distance2_Levenshtypo_Lazy |    440,689.397 ns |     480 B |\n| Distance2_Levenshtypo_Any  |    215,542.244 ns |     480 B |\n| Distance2_Naive            | 68,999,745.833 ns |     700 B |\n| Distance3_Levenshtypo_All  |  1,617,282.340 ns |   25985 B |\n| Distance3_Levenshtypo_Lazy |  2,452,026.901 ns |    1123 B |\n| Distance3_Levenshtypo_Any  |    231,972.804 ns |     584 B |\n| Distance3_Naive            | 71,845,738.624 ns |    4369 B |\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003eLoad all English Language dataset\u003c/summary\u003e\n\n- **Levenshtypo**: This library.\n- **Dictionary**: .NET Dictionary for comparison.\n\n| Method              |          Mean |    Allocated |\n| ------------------- | ------------: | -----------: |\n| English_Dictionary  |  31,755.45 μs |  35524.19 KB |\n| English_Levenshtypo | 142,010.47 μs | 145145.15 KB |\n\n\u003c/details\u003e\n\n---\n\n## 📖 License\n\nMIT — free for personal and commercial use.\n\n---\n\n\u003e Made with ❤️, performance profiling, and typo tolerance by [@andrewjsaid](https://github.com/andrewjsaid)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fandrewjsaid%2Flevenshtypo","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fandrewjsaid%2Flevenshtypo","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fandrewjsaid%2Flevenshtypo/lists"}