Skip to content

Commit 224b334

Browse files
committed
Add ILookup<,> to observable grouped collections
1 parent b522487 commit 224b334

File tree

3 files changed

+45
-4
lines changed

3 files changed

+45
-4
lines changed

CommunityToolkit.Mvvm/Collections/ObservableGroupedCollectionExtensions.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ static void ThrowArgumentExceptionForKeyNotFound()
6969
[MethodImpl(MethodImplOptions.NoInlining)]
7070
static ObservableGroup<TKey, TValue>? FirstOrDefaultWithLinq(ObservableGroupedCollection<TKey, TValue> source, TKey key)
7171
{
72-
return source.FirstOrDefault(group => EqualityComparer<TKey>.Default.Equals(group.Key, key));
72+
return Enumerable.FirstOrDefault<ObservableGroup<TKey, TValue>>(source, group => EqualityComparer<TKey>.Default.Equals(group.Key, key));
7373
}
7474

7575
return FirstOrDefaultWithLinq(source, key);

CommunityToolkit.Mvvm/Collections/ObservableGroupedCollection{TKey,TElement}.cs

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ namespace CommunityToolkit.Mvvm.Collections;
1515
/// </summary>
1616
/// <typeparam name="TKey">The type of the group keys.</typeparam>
1717
/// <typeparam name="TElement">The type of elements in the collection.</typeparam>
18-
public sealed class ObservableGroupedCollection<TKey, TElement> : ObservableCollection<ObservableGroup<TKey, TElement>>
18+
public sealed class ObservableGroupedCollection<TKey, TElement> : ObservableCollection<ObservableGroup<TKey, TElement>>, ILookup<TKey, TElement>
1919
where TKey : notnull
2020
{
2121
/// <summary>
@@ -30,10 +30,17 @@ public ObservableGroupedCollection()
3030
/// </summary>
3131
/// <param name="collection">The initial data to add in the grouped collection.</param>
3232
public ObservableGroupedCollection(IEnumerable<IGrouping<TKey, TElement>> collection)
33-
: base(collection.Select(static c => new ObservableGroup<TKey, TElement>(c)))
33+
: base(collection.Select(static group => new ObservableGroup<TKey, TElement>(group)))
3434
{
3535
}
3636

37+
/// <inheritdoc/>
38+
IEnumerable<TElement> ILookup<TKey, TElement>.this[TKey key]
39+
{
40+
// TODO: optimize this
41+
get => Enumerable.FirstOrDefault<ObservableGroup<TKey, TElement>>(this, item => EqualityComparer<TKey>.Default.Equals(item.Key, key)) ?? Enumerable.Empty<TElement>();
42+
}
43+
3744
/// <summary>
3845
/// Tries to get the underlying <see cref="List{T}"/> instance, if present.
3946
/// </summary>
@@ -46,4 +53,17 @@ internal bool TryGetList([NotNullWhen(true)] out List<ObservableGroup<TKey, TEle
4653

4754
return list is not null;
4855
}
56+
57+
/// <inheritdoc/>
58+
bool ILookup<TKey, TElement>.Contains(TKey key)
59+
{
60+
// TODO: optimize this
61+
return Enumerable.Any<ObservableGroup<TKey, TElement>>(this, item => EqualityComparer<TKey>.Default.Equals(item.Key, key));
62+
}
63+
64+
/// <inheritdoc/>
65+
IEnumerator<IGrouping<TKey, TElement>> IEnumerable<IGrouping<TKey, TElement>>.GetEnumerator()
66+
{
67+
return GetEnumerator();
68+
}
4969
}

CommunityToolkit.Mvvm/Collections/ReadOnlyObservableGroupedCollection{TKey,TElement}.cs

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
// See the LICENSE file in the project root for more information.
44

55
using System;
6+
using System.Collections.Generic;
67
using System.Collections.ObjectModel;
78
using System.Collections.Specialized;
89
using System.Diagnostics.CodeAnalysis;
@@ -15,7 +16,7 @@ namespace CommunityToolkit.Mvvm.Collections;
1516
/// </summary>
1617
/// <typeparam name="TKey">The type of the group keys.</typeparam>
1718
/// <typeparam name="TElement">The type of elements in the collection.</typeparam>
18-
public sealed class ReadOnlyObservableGroupedCollection<TKey, TElement> : ReadOnlyObservableCollection<ReadOnlyObservableGroup<TKey, TElement>>
19+
public sealed class ReadOnlyObservableGroupedCollection<TKey, TElement> : ReadOnlyObservableCollection<ReadOnlyObservableGroup<TKey, TElement>>, ILookup<TKey, TElement>
1920
where TKey : notnull
2021
{
2122
/// <summary>
@@ -37,6 +38,26 @@ public ReadOnlyObservableGroupedCollection(ObservableCollection<ReadOnlyObservab
3738
{
3839
}
3940

41+
/// <inheritdoc/>
42+
IEnumerable<TElement> ILookup<TKey, TElement>.this[TKey key]
43+
{
44+
// TODO: optimize this
45+
get => Enumerable.FirstOrDefault<ReadOnlyObservableGroup<TKey, TElement>>(this, item => EqualityComparer<TKey>.Default.Equals(item.Key, key)) ?? Enumerable.Empty<TElement>();
46+
}
47+
48+
/// <inheritdoc/>
49+
bool ILookup<TKey, TElement>.Contains(TKey key)
50+
{
51+
// TODO: optimize this
52+
return Enumerable.Any<ReadOnlyObservableGroup<TKey, TElement>>(this, item => EqualityComparer<TKey>.Default.Equals(item.Key, key));
53+
}
54+
55+
/// <inheritdoc/>
56+
IEnumerator<IGrouping<TKey, TElement>> IEnumerable<IGrouping<TKey, TElement>>.GetEnumerator()
57+
{
58+
return GetEnumerator();
59+
}
60+
4061
/// <summary>
4162
/// Forwards the <see cref="INotifyCollectionChanged.CollectionChanged"/> event whenever it is raised by the wrapped collection.
4263
/// </summary>

0 commit comments

Comments
 (0)