diff --git a/README.md b/README.md index b5e651a..31c6526 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,258 @@ # X10D -Extension methods on crack +## Extension methods on crack -## About -X10D (pronounced *extend*), is a collection of class libraries that provide various .NET extension methods, including extension methods for Unity, Windows Forms and System.Drawing. +[](https://github.com/oliverbooth/X10D/actions?query=workflow%3A%22.NET+Core%22) +[](https://github.com/oliverbooth/X10D/issues) +[](https://www.nuget.org/packages/X10D/) +[](https://github.com/oliverbooth/X10D/blob/master/LICENSE.md) + +### About +X10D (pronounced *extend*), is a class library that provides extension methods for numerous .NET types. The purpose of this library is to simplify a codebase by reducing the need for repeated code when performing common operations. Simplify your codebase. Take advantage of .NET. Use extension methods. + +*(I'm also [dogfooding](https://deviq.com/dogfooding/) this library, so there's that.)* + +### Table of contents +- [Install](#install) +- [Features](#features) + - [Numeric](#numeric) + - [String](#string) + - [DateTime](#datetime) + - [Enumerable](#enumerable) + - [Enum](#enum) + - [Conversion](#conversion) + - [Random](#random) +- [License](#license) -## Extended Classes You can find the list of classes that have extension methods by viewing the `README.md` file in any of the respective library folders. + +## Install +Install X10D with NuGet via the following command: +```ps +Install-Package X10D -Version 2.0.0 +``` +or by downloading the [latest release](https://github.com/oliverbooth/X10D/releases/latest) from this repository. + +## Features +### Numeric extensions +> 👍 ProTip: *Most* of the extensions available for `int` will also exist for `short`, `long`, and their unsigned counterparts! + +#### `bool` <-> `int` +Convert a `bool` to an `int` by using `ToInt32`. The value returned is 1 if the input is `true`, and 0 if it's `false`. +```cs +bool b = true; + +int i = b.ToInt32(); // 1 +``` +The same also works in reverse. Using `ToBoolean` on an `int` will return `false` if the input is 0, and `true`if the input is anything else. +```cs +int zero = 0; +long nonZero = 1; + +bool b1 = zero.ToBoolean(); // false +bool b2 = nonZero.ToBoolean(); // true +``` + +#### Between +Determine if a value is between other values using `Between` like so: +```cs +int i = 3; + +if (i.Between(2, 4)) +{ + // i is between 2 and 4! +} +``` +Since the signature of this method is defined with a generic constraint of `IComparable`, this will also work for any object that is `IComparable` - not just numeric types! +```cs +bool Between(this T actual, T lower, T upper) where T : IComparable +``` + +#### IsEven (*and IsOdd*) +As the names suggest, this method determines if the input value is evenly divisible by 2. +```cs +int i = 5; +bool b = i.IsEven(); // false +``` +There is also an `IsOdd` extension method, which will return the opposite of that returned by `IsEven`. + +#### IsPrime +Determine if an integral is a prime number by using `IsPrime`. +```cs +bool b = 43.IsPrime(); // true +``` + +#### Clamp +Clamp a value between an upper and lower bound +```cs +int i = 5.Clamp(0, 3); // 3 +``` + +#### Convert degrees <-> radians +Easily convert between radians and degrees +```cs +double rad = 2 * Math.PI; +double deg = rad.RadiansToDegrees(); // 360 + +rad = deg.DegreesToRadians(); // back to 2*pi +``` + +#### Round +Round a value to the nearest whole number: +```cs +var d = 2.75; +var rounded = d.Round(); // 3 +``` +Or specify a value to have it round to the nearest multiple of `x`: +```cs +double a = 8.0.Round(10); // 10 +double b = 2.0.Round(10); // 0 +``` + +### String +#### Repeat value +Repeat a string or a char a specific number of times using `Repeat` +```cs +var c = '-'; +var str = "foo"; + +string repeatedC = c.Repeat(10); // ---------- +string repeatedStr = str.Repeat(5); // foofoofoofoofoo +``` + +#### Base-64 encode/decode +```cs +var base64 = "Hello World".Base64Encode(); // SGVsbG8gV29ybGQ= +var str = "SGVsbG8gV29ybGQ=".Base64Decode(); // Hello World +``` + +### DateTime + +#### Age +Get a rounded integer representing the number of years since a given date. i.e. easily calculate someone's age: +```cs +var dateOfBirth = new DateTime(1960, 7, 16); +int age = dateOfBirth.Age(); // the age as of today +``` +You can also specify a date at which to stop counting the years, by passing an `asOf` date: +```cs +var dateOfBirth = new DateTime(1960, 7, 16); +int age = dateOfBirth.Age(new DateTime(1970, 7, 16)); // 10, the age as of 1970 +``` + +#### To/From Unix Timestamp +Convert to/from a Unix timestamp represented in seconds using `FromUnixTimestamp` on a numeric type, and `ToUnixTimestamp` on a `DateTime`. +```cs +long sec = 1587223415; +DateTime time = sec.FromUnixTimestamp(); // 2020-04-18 15:23:35 +long unix = time.ToUnixTimestamp(); +``` +or represent it with milliseconds by passing `true` for the `isMillis` argument: +```cs +long millis = 1587223415500; +DateTime time = millis.FromUnixTimestamp(true); // 2020-04-18 15:23:35.50 +long unix = time.ToUnixTimestamp(true); +``` + +#### Get first/last day of month +Get the first or last day of the month by using `FirstDayOfMonth` and `LastDayOfMonth` +```cs +var dt = new DateTime(2016, 2, 4); + +DateTime first = dt.FirstDayOfMonth(); // 2016-02-01 +DateTime last = dt.LastDayOfMonth(); // 2016-02-29 (2016 is a leap year) +``` +You can also use `First` or `Last` to get the first or final occurrence of a specific day of the week in a given month: +```cs +var dt = new DateTime(2019, 4, 14); + +DateTime theLastFriday = dt.Last(DayOfWeek.Friday); // 2019-04-24 +DateTime theLastThursday = dt.Last(DayOfWeek.Thursday); // 2019-04-40 +``` + +### Enumerable +#### Split into chunks +Split an `IEnumerable` into an `IEnumerable>`, essentially "chunking" the original IEnumerable into a specific size +```cs +var arr = new int[] { 1, 2, 3, 4, 5, 6, 7, 8 }; +var chunks = arr.Split(2); // split into chunks of 2 + +foreach (var chunk in chunks) +{ + Console.WriteLine(string.Join(", ", chunk)); +} + +// Output: +// 1, 2 +// 3, 4 +// 5, 6 +// 7, 8 +``` +This also works for `string`: +```cs +var str = "Hello World"; +var chunks = str.Split(2); // split string into chunks of 2 + +foreach (var chunk in chunks) +{ + Console.WriteLine(string.Join(string.Empty, chunk)); +} + +// Output: +// He +// ll +// o <-- space is included +// Wo +// rl +// d <-- no space! end of string +``` + +### Enum +#### Parse string into enum +You can use the `EnumParse` method to convert a string into a value from an enum, while optionally ignoring case: +```cs +enum Number +{ + Zero, + One, + Two, + Three, +} + +Number num = "two".EnumParse(true); // num == Number.Two +``` + +#### `Next` / `Previous` enum cycling +Cycle through the values in an enum with `Next` and `Previous`: +```cs +Number two = Number.Two; + +Number one = two.Previous(); +Number three = two.Next(); +``` + +### Conversion +Easily convert between types using `To`, `ToOrNull`, `ToOrDefault`, or `ToOrOther`, thereby shortening the call to `Convert.ChangeType` or `Convert.ToX`: +```CS +int i = "43".To(); +int j = "a".ToOrDefault(); // 0 +int k = "a".ToOrOther(100); // 100 +``` + +### Random +Do more with Random including flip a coin, randomly select an element in an array, or shuffle the array entirely. +```cs +var random = new Random(); + +// flip a coin +bool heads = random.CoinToss(); + +// randomly choose an item +var arr = new int[] { 1, 2, 3, 4 }; +var item = random.OneOf(arr); + +// shuffle an array or list +var shuffled = arr.Shuffle(random); +``` + +## License +X10D is released under the MIT License. See [here](https://github.com/oliverbooth/X10D/blob/master/LICENSE.md) for more details. \ No newline at end of file