ToolBX.OPEX 2.2.0

dotnet add package ToolBX.OPEX --version 2.2.0
NuGet\Install-Package ToolBX.OPEX -Version 2.2.0
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="ToolBX.OPEX" Version="2.2.0" />
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add ToolBX.OPEX --version 2.2.0
#r "nuget: ToolBX.OPEX, 2.2.0"
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
// Install ToolBX.OPEX as a Cake Addin
#addin nuget:?package=ToolBX.OPEX&version=2.2.0

// Install ToolBX.OPEX as a Cake Tool
#tool nuget:?package=ToolBX.OPEX&version=2.2.0

OPEX

OPEX

OverPowered Enumerable eXtensions - It makes your collections OP AF!

Good to know

If you are already familiar with ToolBX.Collections then these extension methods will feel natural. As with the rest of ToolBX, we like to throw a lot but we also provide "Try" overloads for the lazier devs out there.

IsNullOrEmpty

You used to do this

if (collection == null || !collection.Any())
{
	...
}

Now you can do this for the exact same effect

if (collection.IsNullOrEmpty())
{
	...
}

AddRange for everyone!

List<T> has an AddRange method in C# that isn't on any other collection but it definitely should be standard across the board if you ask me. OPEX adds an AddRange extension method to IList<T> which means that it can now be used with any non-fixed collection that implements IList<T>.

var items = _database.GetEverything();
collection.AddRange(items);

Concat for singles!

Isn't it annoying that you have to do this?

var newList = list.Concat(new [] { item }).ToList();

Now you can do this

var newList = list.Concat(item).ToList();

You can even do this

var newList = list.Concat(item1, item2, item3).ToList();

FirstIndexOf and LastIndexOf

Returns the index of the first or last match for your item or predicate in the collection or -1 if there is no match.

var index = collection.FirstIndexOf(item);
var index = collection.FirstIndexOf(x => x.Name == "Roger");

var index = collection.LastIndexOf(item);
var index = collection.LastIndexOf(x => x.Age > 21);

IndexesOf

Returns the index of all matches or an empty collection.

var indexes = collection.IndexesOf(item);
var indexes = collection.IndexOf(x => x.Money <= 12000);

SingleIndexOf

TODO

GetRandomIndex, GetRandom

var index = collection.GetRandomIndex();

var item = collection.GetRandom();

GetManyRandoms

Returns a specified number of unique random items from the collection or the entire, shuffled collection if that number is equal or greather than the collection.

var items = collection.GetManyRandoms(8);

GetManyRandomIndexes

TODO

Shuffle

Reorganizes the collection in a random order.

collection.Shuffle();

//As of 2.2.0, Shuffle() returns the collection so you can chain it
var collection = new List<int> { 1, 2, 3, 4, 5 }.Shuffle();

ToShuffled

Returns a new collection with the same items in a random order.

var shuffled = collection.ToShuffled();

IsWithinRange

Returns true if the index specified is within the collection's range.

if (collection.IsWithinRange(8)) 
{
	...
}

LastIndex

Returns the last index in the collection. Normally, you would do collection.Count - 1 to get this value.

var index = collection.LastIndex();

PopAll

Removes and returns all desired items from a collection. It has overloads for a specific item or a predicate.

var items = collection.PopAll(item);

var items = collection.PopAll(x => x.Name.StartsWith("Bogus"));

PopAt

Removes and returns the item at the specified index. It has an overload for multiple indexes.

var item = collection.PopAt(8);

var items = collection.PopAt(8, 12, 16);

PopAtOrDefault

TODO

TryPopAt

TODO

PopFirst

Removes and returns the first item in the collection. It has an overload for a specific item or a predicate.

var result = collection.PopFirst();

var result = collection.PopFirst(item);

var result = collection.PopFirst(x => x.Name.StartsWith("Bogus"));

PopFirstOrDefault

TODO

TryPopFirst

TODO

PopSingle

TODO

PopSingleOrDefault

TODO

TryPopSingle

TODO

PopLast

Removes and returns the last item in the collection. It has an overload for a specific item or a predicate.

var result = collection.PopLast();

var result = collection.PopLast(item);

var result = collection.PopLast(x => x.Name.StartsWith("Bogus"));

PopLastOrDefault

TODO

TryPopLast

TODO

PopRandom

Removes and returns a random item from the collection.

var result = collection.PopRandom();

PopManyRandoms

Removes and returns a specified number of unique random items from the collection or the entire, shuffled collection if that number is equal or greather than the collection.


## RemoveAll
Removes all occurences from a collection. It has overloads for a specific item or a predicate.
```cs
collection.RemoveAll(item);

collection.RemoveAll(x => x.Name.StartsWith("Bogus"));

RemoveFirst, TryRemoveFirst, RemoveLast and TryRemoveLast

Removes the first or last item in the collection according to the item or predicate specified. Overloads without Try in their name will throw exceptions if nothing is removed.

//Will remove the first item it finds
collection.RemoveFirst(item);

//Or the last
collection.RemoveLast(item);

collection.RemoveFirst(x => x.Id > 2);

collection.TryRemoveLast(x => x.Age == 24);

SequenceEqualOrNull

Behaves like SequenceEqual with the exception that it checks for nulls. In other words, it will not throw exceptions if either or both collections are null. This is especially useful when overloading equality operators where you want to check sequence equality rather than reference equality.

public string? Name { get; init; }

public IReadOnlyList<int>? Ids { get; init; }

public bool Equals(Thingy other)
{
	if (other is null) return false;
	if (ReferenceEquals(this, other)) return true;
	return Name == other.Name && Ids.SequenceEqualOrNull(other.Ids);
}

UnorderedEqualOrNull

Behaves like SequenceEqualOrNull with the exception that it ignores order.

public string? Name { get; init; }

public IReadOnlyList<int>? Ids { get; init; }

public bool Equals(Thingy other)
{
	if (other is null) return false;
	if (ReferenceEquals(this, other)) return true;
	return Name == other.Name && Ids.UnorderedEqualOrNull(other.Ids);
}

Split

Splits a collection into two by keeping the results into two collections in a Splitted<T> object.

//Used like a regular .Where method
var result = collection.Split(x => x.Name.Length > 10);

//Iterates through every item with names that are longer than ten characters
foreach (result.Remaining)
{
	...
}

//Iterates through every item with names that are shorter than or equal to ten characters
foreach (result.Excluded)
{
	...
}

Swap

Swap two indexes toghether.

//Swaps the items at index 3 and 8
collection.Swap(3, 8);

TryGetFirst, TryGetLast and TryGetSingle

These work like LINQ's FirstOrDefault, LastOrDefault and SingleOrDefault except that you're given a TryGetResult<T> instead of T?. The issue with T? is that there is no clear way of knowing whether the method returned default(T) because it could not be found or because that's what was found. TryGetResult<T> makes it clear with its IsSuccess property.

//They are used exactly like their `OrDefault` counterparts
var item = collection.TryGetFirst(x => x.Name == "Seb");

//This is also allowed in case you expect your collection to have exactly one (or no) item
var item = collection.TryGetSingle();

Uniform and UniformOrDefault

Validates that all entries in the collection are "duplicates" (or that the collection is "uniform") and returns any of those entries. It's basically a cleaner alternative to using First or FirstOrDefault in cases where you have more than one entry in the collection but you don't care which entry is returned. What's wrong with First and FirstOrDefault, you say? It should really only be used when your intent is to actually get the first element in the collection. Single or SingleOrDefault should be used instead when there's not supposed to be more than one entry. But sometimes, you just get a garbage collection that you have little to no control over and you just need whichever duplicate entry.

It can also validate that all elements in the list have the same value for a specified property if used with a lambda. All could be used but Uniform returns the "first" of those elements as well.

//Returns any item in the collection if they're all duplicates or throws
var item = collection.Uniform();

//Returns any item in the collection if they're all duplicates or default
var item = collection.UniformOrDefault();

//Returns "Roger" if all items in the collection have "Roger" for a middle name or throws
var item = collection.Uniform(x => x.MiddleName == "Roger");

//Returns "Roger" if all items in the collection have "Roger" for a middle name or null
var item = collection.UniformOrDefault(x => x.MiddleName == "Roger");

UniformBy and UniformByOrDefault

Same as Uniform and UniformOrDefault except that it will return the whole object instead of the property from the lambda. There are no non-lambda overloads of UniformBy and UniformByOrDefault

//Returns the item with "Roger" for a middle name if all items have the same value or throws
var item = collection.UniformBy(x => x.MiddleName == "Roger");

//Returns the item with "Roger" for a middle name if all items have the same value or default
var item = collection.UniformByOrDefault(x => x.MiddleName == "Roger");

Default LINQ methods with custom exceptions and messages

LINQ methods like First, Last, Single, FirstOrDefaut, LastOrDefault and SingleOrDefault all have overloads that take a custom exception and message. This is useful when you want to throw a custom exception with a custom message instead of the default InvalidOperationException and message.

var item = collection.First(x => x.Name == "Seb", new ArgumentException("Seb is not in the collection"));

//Or with a message
var item = collection.First(x => x.Name == "Seb", x => new ArgumentException("Seb is not in the collection"));

//Or with a message
var item = collection.First(x => x.Name == "Seb", "Seb is not in the collection");
Product Compatible and additional computed target framework versions.
.NET net7.0 is compatible.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 was computed.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (5)

Showing the top 5 NuGet packages that depend on ToolBX.OPEX:

Package Downloads
ToolBX.Collections.Grid

An observable, dynamic two-dimensional array.

ToolBX.Collections.Common

Common types for the ToolBX.Collections namespaces. This package should not be referenced by your project directly.

ToolBX.SimpleRepositories.Bundles

Base classes and interfaces for setting up repositories that query bundles of entities.

ToolBX.AwesomeMarkup

Extracts any kind of markup information from a string of characters.

ToolBX.Dummies

A lightweight object generation framework for unit testing purposes

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last updated
2.2.0 6,371 1/13/2024
2.2.0-beta3 199 1/7/2024
2.2.0-beta2 171 12/27/2023
2.2.0-beta1 60 12/20/2023
2.0.3 10,246 6/19/2023
2.0.2 1,108 4/24/2023
2.0.1 133 4/24/2023
2.0.0 669 11/10/2022
2.0.0-beta4 125 10/18/2022
2.0.0-beta3 133 10/3/2022
2.0.0-beta1 277 9/21/2022
1.0.6 1,403 10/18/2022
1.0.5 467 10/3/2022
1.0.4 592 9/7/2022
1.0.3 825 7/28/2022
1.0.2 416 7/5/2022
1.0.1 386 7/4/2022
1.0.0 504 6/27/2022