{"id":20409657,"url":"https://github.com/sleekpanther/numberstringcomparer","last_synced_at":"2026-05-28T21:31:35.152Z","repository":{"id":197023570,"uuid":"691924917","full_name":"SleekPanther/NumberStringComparer","owner":"SleekPanther","description":"A C# Comparer to sort lists of data that could be either numeric of string replacing the default alphabetical sort which doesn't always work for numbers.","archived":false,"fork":false,"pushed_at":"2026-05-27T02:10:46.000Z","size":51,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-05-27T04:13:09.207Z","etag":null,"topics":["noah","noah-patullo","noah-patulo","noahpattulo","noahpatullo","noahpatulo","patullo","sort","sorting"],"latest_commit_sha":null,"homepage":"","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/SleekPanther.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"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}},"created_at":"2023-09-15T07:20:08.000Z","updated_at":"2026-05-27T02:10:50.000Z","dependencies_parsed_at":"2023-10-01T23:25:34.413Z","dependency_job_id":"939bee2d-ff14-4104-bec0-8a426c646464","html_url":"https://github.com/SleekPanther/NumberStringComparer","commit_stats":null,"previous_names":["sleekpanther/numberstringcomparer"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/SleekPanther/NumberStringComparer","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SleekPanther%2FNumberStringComparer","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SleekPanther%2FNumberStringComparer/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SleekPanther%2FNumberStringComparer/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SleekPanther%2FNumberStringComparer/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/SleekPanther","download_url":"https://codeload.github.com/SleekPanther/NumberStringComparer/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SleekPanther%2FNumberStringComparer/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33627934,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-05-28T02:00:06.440Z","response_time":99,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"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":["noah","noah-patullo","noah-patulo","noahpattulo","noahpatullo","noahpatulo","patullo","sort","sorting"],"created_at":"2024-11-15T05:42:51.373Z","updated_at":"2026-05-28T21:31:35.147Z","avatar_url":"https://github.com/SleekPanther.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"# NumberStringComparer\nA C# Comparer to sort lists of data that could be either numeric of string replacing the default alphabetical sort which doesn't always work for numbers.\n\n## The Problem\nThe default alphabetical sort doesn't work when numbers are stored as strings.  \nExample 1:\n```\nvar list1 = new List\u003cstring\u003e(){\n    \"1\",\n    \"2\",\n    \"3\",\n    \"10\",\n    \"11\",\n    \"100\",\n};\nlist1.Sort();\n\n// Result: string.Join(Environment.NewLine, list1);\n\n\"1\"\n\"10\"\n\"100\"\n\"11\"\n\"2\"\n\"3\"\n```\nExample 2: \n```\nvar list3 = new List\u003cobject\u003e(){\n    \"1\",\n    \"2\",\n    \"3\",\n    \"10\",\n    \"11\",\n    \"100\",\n    \"A\",\n    \"a\",\n    \"b\",\n    \"ab\",\n};\nlist3.Sort();\n\n// Result: \n\"1\"\n\"10\"\n\"100\"\n\"11\"\n\"2\"\n\"3\"\n\"A\"\n\"a\"\n\"b\"\n\"ab\"\n```\n\nExample 3: Combined lists containing both numbers and strings because you can't parse every item as numbers and it fails to compare items of different types.\n```\nvar list3 = new List\u003cobject\u003e(){\n    1,\n    2,\n    3,\n    10,\n    11,\n    100,\n    \"A\",\n    \"a\",\n    \"b\",\n    \"ab\",\n};\nlist3.Sort();\n```\n```diff\nResult:\n- InvalidOperationException: 'Failed to compare two elements in the array.'\n```\n\n## Solution\n`NumberStringComparer\u003cT\u003e` parses each item into a `NumberString\u003cT\u003e` object composed of a `text` property containing the original text and if the item is numeric also a `number` component. If an item is not completely numeric, `number` will be null and the text is parsed into a list of `parts` containing the text broken up into its numeric and non-numeric parts.  \ne.g. \"a122bc4\" will result in `parts` = `[\"a\", 122, \"bc\", 4]`  \nItems are compared by number if they are completely numeric, otherwise each parts list will be compared for sorting.\nIf the text contains commas, is broken up into a parts array of numbers, removing the commas.\ne.g. \"1,2,3\" will result in `[1, 2, 3]` and \"1,2\" will result in `[1, 2]` and when sorting, \"1,2\" will come before \"1,2,3\"\n\n## Comparing complex objects by 1 property\nYou can use any of the following primitive collection types\n### Supported data types\n- `string`\n- `int`\n- `double`\n- `float`\n- `decimal`\n- `long`\n- `short`\n\nAs well as complex objects or Dictionaries using a property.\nFor Dictionaries, it will use the key property of `KeyValuePair` and ignore the Value property.\nSee `NumberStringComparerTests.NumberStringComparerObjectComparison_Tests()` for more complex object comparison examples.\n\n### .NET Version\nThis project uses .NET 9.0 for the main branch but there is also a [.NET Framework-compatible branch](https://github.com/SleekPanther/NumberStringComparer/tree/net-framework) made with only a few minor changes.\n- Replacing `readonly` properties with private fields and properties with private do nothing setters.\n- Replace uses of the Range operator with the `SubStringSafe` extension methods.\n- Explicitly specify the object type on the right hand of equals replacing `new()`\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsleekpanther%2Fnumberstringcomparer","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsleekpanther%2Fnumberstringcomparer","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsleekpanther%2Fnumberstringcomparer/lists"}