mirror of
https://github.com/BililiveRecorder/BililiveRecorder.git
synced 2024-11-16 03:32:20 +08:00
72 lines
3.2 KiB
C#
72 lines
3.2 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
|
|
namespace BililiveRecorder.WPF
|
|
{
|
|
internal static class EnumerableExtensions
|
|
{
|
|
/// <summary>
|
|
/// Returns the elements with the maximum key value by using the default comparer to compare key values.
|
|
/// </summary>
|
|
/// <typeparam name="TSource">Source sequence element type.</typeparam>
|
|
/// <typeparam name="TKey">Key type.</typeparam>
|
|
/// <param name="source">Source sequence.</param>
|
|
/// <param name="keySelector">Key selector used to extract the key for each element in the sequence.</param>
|
|
/// <returns>List with the elements that share the same maximum key value.</returns>
|
|
public static IList<TSource> MaxBy<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector)
|
|
{
|
|
if (source == null) { throw new ArgumentNullException("source"); }
|
|
if (keySelector == null) { throw new ArgumentNullException("keySelector"); }
|
|
|
|
return MaxBy(source, keySelector, Comparer<TKey>.Default);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Returns the elements with the minimum key value by using the specified comparer to compare key values.
|
|
/// </summary>
|
|
/// <typeparam name="TSource">Source sequence element type.</typeparam>
|
|
/// <typeparam name="TKey">Key type.</typeparam>
|
|
/// <param name="source">Source sequence.</param>
|
|
/// <param name="keySelector">Key selector used to extract the key for each element in the sequence.</param>
|
|
/// <param name="comparer">Comparer used to determine the maximum key value.</param>
|
|
/// <returns>List with the elements that share the same maximum key value.</returns>
|
|
public static IList<TSource> MaxBy<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector, IComparer<TKey> comparer)
|
|
{
|
|
if (source == null) { throw new ArgumentNullException("source"); }
|
|
if (keySelector == null) { throw new ArgumentNullException("keySelector"); }
|
|
if (comparer == null) { throw new ArgumentNullException("comparer"); }
|
|
|
|
return ExtremaBy(source, keySelector, (key, minValue) => comparer.Compare(key, minValue));
|
|
}
|
|
|
|
private static IList<TSource> ExtremaBy<TSource, TKey>(IEnumerable<TSource> source, Func<TSource, TKey> keySelector, Func<TKey, TKey, int> compare)
|
|
{
|
|
var result = new List<TSource>();
|
|
|
|
using (var e = source.GetEnumerator())
|
|
{
|
|
if (!e.MoveNext()) { throw new InvalidOperationException("Source sequence doesn't contain any elements."); }
|
|
|
|
var current = e.Current;
|
|
var resKey = keySelector(current);
|
|
result.Add(current);
|
|
|
|
while (e.MoveNext())
|
|
{
|
|
var cur = e.Current;
|
|
var key = keySelector(cur);
|
|
|
|
var cmp = compare(key, resKey);
|
|
if (cmp == 0) { result.Add(cur); }
|
|
else if (cmp > 0)
|
|
{
|
|
result = new List<TSource> { cur };
|
|
resKey = key;
|
|
}
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
}
|
|
}
|