{"id":17652197,"url":"https://github.com/impworks/utils","last_synced_at":"2025-05-06T21:06:04.461Z","repository":{"id":33434655,"uuid":"132601523","full_name":"impworks/utils","owner":"impworks","description":"Personal collection of various helper methods","archived":false,"fork":false,"pushed_at":"2024-06-05T18:27:53.000Z","size":123,"stargazers_count":14,"open_issues_count":1,"forks_count":1,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-05-06T21:05:20.514Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"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/impworks.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":"2018-05-08T11:51:47.000Z","updated_at":"2024-06-05T18:27:56.000Z","dependencies_parsed_at":"2025-05-06T21:05:20.784Z","dependency_job_id":null,"html_url":"https://github.com/impworks/utils","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/impworks%2Futils","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/impworks%2Futils/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/impworks%2Futils/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/impworks%2Futils/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/impworks","download_url":"https://codeload.github.com/impworks/utils/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252769396,"owners_count":21801376,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":[],"created_at":"2024-10-23T11:46:10.318Z","updated_at":"2025-05-06T21:06:04.441Z","avatar_url":"https://github.com/impworks.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Impworks.Utils\n\n![AppVeyor](https://img.shields.io/appveyor/ci/impworks/Utils.svg) ![AppVeyor Tests](https://img.shields.io/appveyor/tests/impworks/Utils.svg) [![NuGet](https://img.shields.io/nuget/v/Impworks.Utils.svg)](https://www.nuget.org/packages/Impworks.Utils/) ![NuGet Downloads](https://img.shields.io/nuget/dt/Impworks.Utils.svg)\n\nA collection of useful helper methods.\n\n## Installation\n\nTo install, use the following Package Manager command:\n\n```\nPM\u003e Install-Package Impworks.Utils\n```\n\n## Usage\n\nAdd the `using` directive with the required namespace to the top of the file where you intend to use a helper method.\n\nIf you work with Resharper, it will suggest adding the namespace automatically.\n\n## The methods\n\nThe package provides the following methods, split into logical parts.\n\n  * Strings\n  \n      Parsing to various types (primitives supported by default):\n      ```csharp\n      \"123\".Parse\u003cint\u003e() // 123\n      \"hello\".TryParse\u003cint?\u003e() // null\n      \"12345\".TryParse\u003cMyType\u003e(MyParseFunc) // MyType\n      \"1,2,test,3\".TryParseList\u003cint\u003e() // 1, 2, 3\n      \"1;2;test;3\".TryParseList\u003cint\u003e(separator: \";\") // 1, 2, 3\n      \"1\".TryParse\u003cMyEnum?\u003e(); // MyEnum or null\n      ```\n      Coalesce:\n      ```csharp\n      StringHelper.Coalesce(null, \"\", \"test\") // test\n      ```\n      Ends/starts with substring:\n      ```csharp\n      \"hello world\".StartsWithPart(\"hello test\", 5) // true\n      \"a test\".EndsWithPart(\"b TEST\", 4, ignoreCase: true) // true\n      ```\n      Transliteration from Russian:\n      ```csharp\n      StringHelper.Transliterate(\"Привет мир\", \"_\") // \"Privet_mir\"\n      ```\n      `string.Join` as extension:\n      ```csharp\n      new [] { 1, 2, 3 }.JoinString(\", \") // \"1, 2, 3\"\n      ```\n\n  * Enumerable\n\n      `Distinct` by projection:\n      ```csharp\n      new [] { 1, 2, 3 }.DistinctBy(x =\u003e x % 2) // 1, 2\n      ```\n      Conditional ordering:\n      ```csharp\n      new [] { 4, 6, 1 }.OrderBy(x =\u003e x, isDescending) // true =\u003e 6, 4, 1, false =\u003e 1, 4, 6\n      new [] { obj1, obj2 }.OrderBy(\"FieldA.FieldB\", isDescending) // orders by field or path\n      ```\n      Partitioning:\n      ```csharp\n      new [] { 1, 2, 3, 4, 5, 6 }.PartitionBySize(2) // [1, 2], [3, 4], [5, 6]\n      new [] { 1, 2, 3, 4, 5, 6 }.PartitionByCount(2) =\u003e [1, 2, 3], [4, 5, 6]\n      ```\n      Recursive selection and application:\n      ```csharp\n      new [] { treeRoot }.SelectRecursively(x =\u003e x.Children) // selects all children in a flat list\n      new [] { treeRoot }.ApplyRecursively(x =\u003e x.Children, x =\u003e x.Value = 1) // sets Value = 1 on all children\n      ```\n      Destructuring sequences:\n      ```csharp\n      var (a, b) = new [] { 1, 2, 3 }.First2(); // a = 1, b = 2\n      var (c, d, e, f) = new [] { \"foo\", \"bar\" }.First4OrDefault(); // e, f = null\n      ```\n\n  * Expressions\n\n      Expression combinations (useful for LINQ):\n      ```csharp\n      ExprHelper.And\u003cFoo\u003e(x =\u003e x.A == 1, x =\u003e x.B == 2) // x =\u003e x.A == 1 \u0026\u0026 x.B == 2\n      ExprHelper.Or\u003cFoo\u003e(x =\u003e x.A == 1, x =\u003e x.B == 2) // x =\u003e x.A == 1 || x.B == 2\n      ```\n      Partial application (for `Func` and `Action` up to 8 arguments):\n      ```csharp\n      ExprHelper.Apply((int x, int y) =\u003e x + y, 10) // Expr for (int x) =\u003e x + 10\n      ```\n\n  * Enums\n\n      Captions from `Description` attribute:\n      ```csharp\n      enum Language\n      {\n          [Description(\"C#\")] CSharp,\n          [Description(\"C++\")] CPlusPlus\n      }\n      EnumHelper.GetEnumDescriptions\u003cLanguage\u003e() // { Language.CSharp = \"C#\", Language.CPlusPlus = \"C++\" }\n      ```\n      Case-insensitive IsDefined:\n      ```csharp\n      EnumHelper.IsDefined\u003cLanguage\u003e(\"csharp\") // true\n      ```\n\n  * Exceptions\n\n      Fluent exception ignoring (with async versions too):\n      ```csharp\n      Try.Do(() =\u003e SomeStuff()); // does not throw\n      Try.Get(() =\u003e GetAnInt()) // returns 0 on exception\n      Try.Get(() =\u003e GetAnInt(), 123) // returns 123 on exception\n      ```\n\n  * Comparisons\n\n      Min and Max for all IComparable's:\n      ```csharp\n      CompareHelper.Min(\"b\", \"a\", \"c\") // \"a\"\n      CompareHelper.Max(DateTime.Parse(\"2024-01-01\"), DateTime.Parse(\"2023-02-01\")) // 2024-01-01\n      ```\n\n  * Random\n\n      Random values:\n      ```csharp\n      RandomHelper.Int(1, 100) // 42\n      RandomHelper.Float() // 0.1337\n      RandomHelper.Sign() // -1 or 1\n      RandomHelper.DoubleNormal() // normal distribution around 0.5 limited to 0..1\n      ```\n      Random picks:\n      ```csharp\n      RandomHelper.Pick(1, 2, 3, 4, 5) // 4\n      RandomHelper.PickWeighted(new [] { \"a\", \"test\", \"blablabla\" }, x =\u003e x.Length) // likely \"blablabla\"\n      new [] { 1, 2, 3, 4, 5 }.PickRandom() // optionally accepts a weight function too\n      ```\n      Shuffle:\n      ```\n      new [] { 1, 2, 3, 4, 5 }.Shuffle() // something like 4, 2, 1, 5, 3\n      ```\n\n  * Dictionary\n\n      Value retrieval:\n      ```csharp\n      var dict = new Dictionary\u003cstring, int\u003e { [\"hello\"] = 1, [\"world\"] = 2 };\n      dict.TryGetValue(\"hello\") // 1\n      dict.TryGetValue(\"test\") // 0\n      dict.TryGetValue(\"foo\", null, \"hello\") // 1\n      dict.TryGetNullableValue(\"test\") // null\n      ```\n\n  * Urls\n\n      URL parts combination:\n      ```csharp\n      UrlHelper.Combine(\"http://a.com/foo\", \"bar/\", \"/test\") // http://a.com/foo/bar/test\n      ```\n      Query generation from an object (accepts anonymous objects, `Dictionary` and `JObject`):\n      ```csharp\n      UrlHelper.GetQuery(new { A = 1, B = \"hello\" }) // \"A=1\u0026B=hello\"\n      UrlHelper.GetQuery(new { A = new [] { 1, 2, 3 } }) // \"A=1\u0026A=2\u0026A=3\"\n      ```\n\n  * Tasks (.NET Standard 2.0 only)\n\n      Parallel awaiting (strong typing, up to 7 values):\n      ```csharp\n      var (i, str) = await TaskHelper.GetAll(\n          GetIntAsync(),\n          GetStringAsync()\n      );\n      ```\n      Async ID-based locker:\n      ```csharp\n      var locker = new Locker\u003cint\u003e();\n      using(await locker.AcquireAsync(123))\n          // do stuff\n      ```\n\n  * XML\n\n      Attributes:\n      ```csharp\n      var xml = XElement.Parse(@\"\u003ctest a=\"\"1337\"\" b=\"\"true\"\" /\u003e\");\n      xml.Attr(\"a\") // \"1337\"\n      xml.ParseAttr\u003cint\u003e(\"a\") // 1337\n      xml.ParseAttr\u003cbool\u003e(\"b\") // true\n      xml.TryParseAttr\u003cbool?\u003e(\"a\") // null\n      ```\n      Less verbose serialization with a cleaner resulting XML:\n      ```csharp\n      var obj = new MyObject { Foo = \"hello\", Bar = (int?) null };\n      XmlHelper.Serialize(obj) // \u003cMyObject\u003e\u003cFoo\u003eHello\u003c/Foo\u003e\u003cBar /\u003e\u003c/MyObject\u003e\n      XmlHelper.Serialize(obj, clean: false); // lots of junk: xml declaration, namespaces, nil's\n      XmlHelper.Deserialize\u003cMyObject\u003e(\"...\") // gets it back\n       ```","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fimpworks%2Futils","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fimpworks%2Futils","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fimpworks%2Futils/lists"}