Epiforge.Extensions.Collections
4.1.0
dotnet add package Epiforge.Extensions.Collections --version 4.1.0
NuGet\Install-Package Epiforge.Extensions.Collections -Version 4.1.0
<PackageReference Include="Epiforge.Extensions.Collections" Version="4.1.0" />
<PackageVersion Include="Epiforge.Extensions.Collections" Version="4.1.0" />
<PackageReference Include="Epiforge.Extensions.Collections" />
paket add Epiforge.Extensions.Collections --version 4.1.0
#r "nuget: Epiforge.Extensions.Collections, 4.1.0"
#:package Epiforge.Extensions.Collections@4.1.0
#addin nuget:?package=Epiforge.Extensions.Collections&version=4.1.0
#tool nuget:?package=Epiforge.Extensions.Collections&version=4.1.0
This library provides a number of extension methods for collections and dictionaries:
EnumerableExtensions, providing:FindIndex- Finds the index of the first element in the source that satisfies the specified predicateFindLastIndex- Finds the index of the last element in the source that satisfies the specified predicateFindIndicies- Finds the indicies of the elements in the source that satisfy the specified predicateIndexOf- Finds the first index of the specified item in the sourceLastIndexOf- Finds the last index of the specified item in the sourceIndiciesOf- Finds the indicies of the specified item in the source
DictionaryExtensions, providing:GetOrAdd- Adds a key/value pair to the specifiedIDictionaryorIDictionary<TKey, TValue>by using the specified function if the key does not already exist (returns the new value, or the existing value if the key exists)TryRemove- Attempts to remove and return the value that has the specified key from the specifiedIDictionaryorIDictionary<TKey, TValue>
Generic
ReadOnlyDictionary<TKey, TValue>is a read-only wrapper for any classes implementingIReadOnlyDictionary<TKey, TValue>ReadOnlyRangeDictionary<TKey, TValue>is a read-only wrapper for any classes implementingIReadOnlyRangeDictionary<TKey, TValue>ReadOnlyConcurrentDictionary<TKey, TValue>is a read-only wrapper forObservableConcurrentDictionary<TKey, TValue>ReversedComparer<T>is a comparer that reverses the comparison of another comparer (this is useful when you want to sort a list in the opposite order of the default sort order)IHashKeys<TKey>is implemented by keyed data structures that use anIEqualityComparer<TKey>to decide key equality, so that a consumer can discover the comparer a dictionary is actually using rather than assume the default (the observable queries inEpiforge.Extensions.Expressionsdo exactly this)PrefixWeightedSequence<T>is a sequence in which every position carries a weight. Insertion, removal, movement, and changing a weight are all logarithmic in the number of positions, as is finding a position by index, by the sum of the weights before it, or by which position a given offset falls within.PrefixWeightedSequenceNode<T>is the handle to a position and remains valid for as long as its item remains in the sequence, so you can hold onto one instead of re-finding an index after every change. When you are looking for a position near one you already have in hand, hand that node back withNodeAtFromorNodeAtWeightFromand the search costs the logarithm of the distance between the two rather than the logarithm of the whole sequence, which makes walking a sequence by position nearly as cheap as enumerating it. When you want the total weight before a position you are already holding, hand the node itself toPrefixWeightBeforerather than taking its index first and asking about that: the node climbs to the root once, where the pair walks the tree twice. If you are assigning a weight and want that total as well, the overload ofSetWeighttaking anoutparameter accumulates it along the climb which repairs the tree; the overload without one does not, because a caller who will not read it should not pay to carry it.
ObjectModel
ObservableDictionary<TKey, TValue>,ObservableSortedDictionary<TKey, TValue>,ObservableConcurrentDictionary<TKey, TValue>are counterparts to the BCL'sDictionary<TKey, TValue>,SortedDictionary<TKey, TValue>, andConcurrentDictionary<TKey, TValue>, respectively, that implement the also includedIRangeDictionary<TKey, TValue>andINotifyDictionaryChanged<TKey, TValue>. Ever want to add multiple items to a dictionary at once... or keep an eye on what's being done to it? Now you can.ObservableRangeCollection<T>is a counterpart to the BCL'sObservableCollection<T>which implements:AddRange- Adds objects to the end of the collectionGetAndRemoveAll- Removes all object from the collection that satisfy a predicateGetAndRemoveAt- Gets the element at the specified index and removes it from the collectionGetRange- Gets the elements in the range starting at the specified index and of the specified lengthInsertRange- Inserts elements into the collection at the specified indexMoveRange- Moves the items at the specified index to a new location in the collectionRemoveAll- Removes all object from the collection that satisfy a predicateRemoveRange- Removes the specified items from the collection or removes the specified range of items from the collectionReplaceAll- Replace all items in the collection with the items in the specified collectionReplaceRange- Replaces the specified range of items from the collection with the items in the specified collectionReset- Resets the collection with the specified collection of itemsResetRemovingAll- Removes all objects from the collection that satisfy a predicate, announcing it with a single event
ReadOnlyObservableRangeDictionary<TKey, TValue>is a read-only wrapper for any classes implementingIReadOnlyObservableRangeDictionary<TKey, TValue>. It subscribes to what it wraps, so dispose of it when you are done with it.ReadOnlyObservableRangeCollection<T>is a read-only wrapper for any classes implementingIReadOnlyObservableRangeCollection<T>. It subscribes to what it wraps, so dispose of it when you are done with it.
Specialized
EquatableList<T>is an immutable list of items which may be compared with other instances of the same type and produces a hash code based on the permutation of its contents.NullableKeyDictionary<TKey, TValue>andNullableKeySortedDictionary<TKey, TValue>are very slim implementations ofIDictionary<TKey, TValue>that allow a single null key (useful for some edge cases in which a null key is simply going to happen and you need to be able to deal with it; otherwise, use other dictionary classes).OrderedHashSet<T>is a counterpart to the BCL'sHashSet<T>that maintains the order of the elements in the set. All operations are still O(1), just like the original, but if you enumerate over it you will get elements in the exact order they were added. There are also methods for manipulating the order.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net6.0 is compatible. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. 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 is compatible. 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. net9.0 is compatible. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net10.0
- Epiforge.Extensions.Components (>= 4.2.0)
-
net6.0
- Epiforge.Extensions.Components (>= 4.2.0)
- System.Collections.Immutable (>= 8.0.0)
-
net7.0
- Epiforge.Extensions.Components (>= 4.2.0)
- System.Collections.Immutable (>= 8.0.0)
-
net8.0
- Epiforge.Extensions.Components (>= 4.2.0)
-
net9.0
- Epiforge.Extensions.Components (>= 4.2.0)
NuGet packages (2)
Showing the top 2 NuGet packages that depend on Epiforge.Extensions.Collections:
| Package | Downloads |
|---|---|
|
Epiforge.Extensions.Expressions
This package assists in operating with expressions. |
|
|
Epiforge.Extensions.Frameworks.WPF
This package assists in developing WPF-based applications. |
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 4.1.0 | 32 | 9/2/2026 |
| 4.0.0 | 49 | 8/31/2026 |
| 3.1.0 | 114 | 8/29/2026 |
| 3.0.0 | 186 | 8/27/2026 |
| 2.1.1 | 436 | 4/14/2026 |
| 2.0.1 | 341 | 12/24/2025 |
| 2.0.0 | 436 | 4/17/2025 |
| 1.5.0 | 404 | 8/24/2023 |
| 1.4.0 | 350 | 8/24/2023 |
| 1.3.2 | 682 | 8/15/2023 |
| 1.3.1 | 500 | 8/13/2023 |
| 1.2.3 | 307 | 8/12/2023 |
| 1.2.1 | 309 | 8/10/2023 |
| 1.1.0 | 321 | 8/8/2023 |
| 1.0.0 | 311 | 6/23/2023 |
CopyTo on an OrderedHashSet, given a number of elements to copy, now walks the set and writes into the array it was handed rather than building an intermediate list and copying out of that. Copying five thousand elements took nine microseconds and twenty kilobytes and now takes four microseconds and nothing at all. The exceptions this method throws for a null array, a negative array index or an array with insufficient space remain of the same types, though their messages now come from this package rather than from the list it used to delegate to; an array index beyond the end of the array is now rejected even when no elements are to be copied, which was not previously specified.
CopyTo on an OrderedHashSet, given a number of elements to copy, no longer casts the set to the sequence it already is before reading it.
RemoveWhere on an OrderedHashSet no longer wraps the snapshot it takes of the set in a read-only view before walking it. The snapshot is a local which nothing else can reach, so the view protected nothing; it remains a snapshot, so a predicate which modifies the set while the sweep is running behaves exactly as it did.
PrefixWeightedSequence now offers PrefixWeightBefore for a node as well as for a position. Asking for the position first and then for the weight preceding that position walks the sequence twice, once up from the node and once down from the root; taking the node directly climbs to the root once. Six places in Epiforge.Extensions.Expressions asked the composed question, one of them on the path a filtered query takes every time an element joins or leaves it.
PrefixWeightedSequence now offers an overload of SetWeight which reports the total weight of the items preceding the node it was given. Repairing the tree after an assignment climbs from the node to the root, which is the same path that weight accumulates over, so a caller which needs both walks the tree once instead of twice. Accumulating it costs more than the climb it rides on, which is why a caller which does not need it keeps a method that does not.