diff --git a/osu.Game/Screens/Select/Carousel/CarouselBeatmapSet.cs b/osu.Game/Screens/Select/Carousel/CarouselBeatmapSet.cs
index 6d2e938fb7..cee68cf9a5 100644
--- a/osu.Game/Screens/Select/Carousel/CarouselBeatmapSet.cs
+++ b/osu.Game/Screens/Select/Carousel/CarouselBeatmapSet.cs
@@ -91,19 +91,19 @@ namespace osu.Game.Screens.Select.Carousel
break;
case SortMode.LastPlayed:
- comparison = -compareUsingAggregateMax(otherSet, b => (b.LastPlayed ?? DateTimeOffset.MinValue).ToUnixTimeSeconds());
+ comparison = -compareUsingAggregateMax(otherSet, static b => (b.LastPlayed ?? DateTimeOffset.MinValue).ToUnixTimeSeconds());
break;
case SortMode.BPM:
- comparison = compareUsingAggregateMax(otherSet, b => b.BPM);
+ comparison = compareUsingAggregateMax(otherSet, static b => b.BPM);
break;
case SortMode.Length:
- comparison = compareUsingAggregateMax(otherSet, b => b.Length);
+ comparison = compareUsingAggregateMax(otherSet, static b => b.Length);
break;
case SortMode.Difficulty:
- comparison = compareUsingAggregateMax(otherSet, b => b.StarRating);
+ comparison = compareUsingAggregateMax(otherSet, static b => b.StarRating);
break;
case SortMode.DateSubmitted:
@@ -127,12 +127,40 @@ namespace osu.Game.Screens.Select.Carousel
///
/// All beatmaps which are not filtered and valid for display.
///
- protected IEnumerable ValidBeatmaps => Beatmaps.Where(b => !b.Filtered.Value || b.State.Value == CarouselItemState.Selected).Select(b => b.BeatmapInfo);
+ protected IEnumerable ValidBeatmaps
+ {
+ get
+ {
+ foreach (var item in Items) // iterating over Items directly to not allocate 2 enumerators
+ {
+ if (item is CarouselBeatmap b && (!b.Filtered.Value || b.State.Value == CarouselItemState.Selected))
+ yield return b.BeatmapInfo;
+ }
+ }
+ }
+
+ ///
+ /// Whether there are available beatmaps which are not filtered and valid for display.
+ /// Cheaper alternative to .Any()
+ ///
+ public bool HasValidBeatmaps
+ {
+ get
+ {
+ foreach (var item in Items) // iterating over Items directly to not allocate 2 enumerators
+ {
+ if (item is CarouselBeatmap b && (!b.Filtered.Value || b.State.Value == CarouselItemState.Selected))
+ return true;
+ }
+
+ return false;
+ }
+ }
private int compareUsingAggregateMax(CarouselBeatmapSet other, Func func)
{
- bool ourBeatmaps = ValidBeatmaps.Any();
- bool otherBeatmaps = other.ValidBeatmaps.Any();
+ bool ourBeatmaps = HasValidBeatmaps;
+ bool otherBeatmaps = other.HasValidBeatmaps;
if (!ourBeatmaps && !otherBeatmaps) return 0;
if (!ourBeatmaps) return -1;
diff --git a/osu.Game/Screens/Select/Carousel/CarouselGroup.cs b/osu.Game/Screens/Select/Carousel/CarouselGroup.cs
index b2ca117cec..62d694976f 100644
--- a/osu.Game/Screens/Select/Carousel/CarouselGroup.cs
+++ b/osu.Game/Screens/Select/Carousel/CarouselGroup.cs
@@ -2,6 +2,8 @@
// See the LICENCE file in the repository root for full licence text.
using System.Collections.Generic;
+using osu.Framework.Extensions.ListExtensions;
+using osu.Framework.Lists;
namespace osu.Game.Screens.Select.Carousel
{
@@ -12,7 +14,7 @@ namespace osu.Game.Screens.Select.Carousel
{
public override DrawableCarouselItem? CreateDrawableRepresentation() => null;
- public IReadOnlyList Items => items;
+ public SlimReadOnlyListWrapper Items => items.AsSlimReadOnly();
public int TotalItemsNotFiltered { get; private set; }