最接近的可能较低值

  • 本文关键字:最接近 c# .net linq
  • 更新时间 :
  • 英文 :

struct StreamInfo
{
    public Stream Stream {get; set;}
    public Quality Quality {get; set;}
}
public enum Quality
{
    VeryLow,
    Low,
    Medium,
    High,
    Maximum,
}
List<StreamInfo> streamInfos;
private Stream NearestLowerPossibleValue(Quality quality)
{
    ....
}

我有带有StreamPhotoQuality的结构StreamInfo列表。我需要从集合中选择最接近可能的值的函数。这意味着,如果我在列表中有具有LowMediumMaximum品质的StreamInfo。我打电话NearestLowerPossibleValue(Quality.High)我需要获得中等质量的流,因为缺少高,如果有高,我想获得高质量的流。我正在寻找一些不错的解决方案,因为我没有发明任何好的解决方案。谢谢你的想法。

private static Stream NearestLowerPossibleValue(Quality preferedQuality)
{
    var streamInfoWithHigherQualityThanPreferred = streamInfos.Where(i => i.Quality <= preferedQuality);
    var mostSimilarToPreferred = streamInfoWithHigherQualityThanPreferred.MaxBy(i => i.Quality);
    return mostSimilarToPreferred.Stream;
}

如果 streamInfos 为 null 或为空,或者 streamInfos 不包含小于或等于首选质量的元素,则引发异常。我使用来自nuget包MoreLing的函数MaxBy,但如果你不能添加这个包,你可以使用:

public static class Extensions
{
    public static TSource MaxBy<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> selector)
    {
        return source.MaxBy<TSource, TKey>(selector, Comparer<TKey>.Default);
    }
    public static TSource MaxBy<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> selector, IComparer<TKey> comparer)
    {
        if (source == null)
        {
            throw new ArgumentNullException("source");
        }
        if (selector == null)
        {
            throw new ArgumentNullException("selector");
        }
        if (comparer == null)
        {
            throw new ArgumentNullException("comparer");
        }
        using (IEnumerator<TSource> enumerator = source.GetEnumerator())
        {
            if (!enumerator.MoveNext())
            {
                throw new InvalidOperationException("Sequence contains no elements");
            }
            TSource current = enumerator.Current;
            TKey y = selector(current);
            while (enumerator.MoveNext())
            {
                TSource arg = enumerator.Current;
                TKey x = selector(arg);
                if (comparer.Compare(x, y) > 0)
                {
                    current = arg;
                    y = x;
                }
            }
            return current;
        }
    }
}
public enum Quality
{
    VeryLow=1,
    Low=2,
    Medium=3,
    High=4,
    Maximum=5,
}
private PhotoQuality NearestLowerPossibleValue(PhotoQuality quality)
{
   int lenny = (int)quality;
   if (lenny != 1) lenny--;
   return (PhotoQuality)lenny;
}

如果你可以修改StreamInfo结构,我建议你实现IComparable接口:

struct StreamInfo : IComparable<StreamInfo>
{
    public Stream Stream { get; set; }
    public PhotoQuality Quality { get; set; }
    public int CompareTo(StreamInfo other)
    {
        return Quality - other.Quality;
    }
}
public enum PhotoQuality
{
    VeryLow,
    Low,
    Medium,
    High,
    Maximum,
}
List<StreamInfo> streamInfos;
private Stream NearestLowerPossibleValue(PhotoQuality quality)
{
    return streamInfos.Where(si => si.Quality <= quality).Max().Stream;
}

如果没有,我们总是可以使用Aggregate方法:

private Stream NearestLowerPossibleValue(PhotoQuality quality)
{
    return streamInfos.Where(si => si.Quality <= quality)
        .Aggregate((si1, si2) => si1.Quality > si2.Quality ? si1 : si2).Stream;
}

利用枚举的整数值:

public enum Quality
{
    VeryLow,
    Low,
    Medium,
    High,
    Maximum,
}
IEnumerable<Quality> qualities = new List<Quality>
{
    Quality.Low,
    Quality.Medium,
    Quality.Maximum
};
Quality preferedQuality = Quality.High;
Quality actualQuality = qualities
    .TakeWhile(quality => quality <= preferedQuality) // arrow phun
    .Max(); // will throw if qualities is empty
Assert.AreEqual(Quality.Medium, actualQuality);

相关内容

  • 没有找到相关文章

最新更新