LINQ:如何返回不同于min()使用的字段

时间:2010-12-08 14:40:10

标签: c# linq .net-3.5

我正在使用列表(data.Tags)中的IEnumerable Dictionary (masterList)

这是我正在做的典型查询(有效):

var tagList = 
    (from data in masterList
    from tag in data.Tags
    where tag.id == 0x10
    select tag).Distinct(new TagComparer());

tag类包含字段IdValueTranslatedValue。我想根据Id进行搜索,使用Value确定哪个是最小值,然后返回TranslatedValue(而不是Value)。

到目前为止,我的所有尝试都抛出了ArgumentException,例如:

var tagList = 
    (from data in masterList
    from tag in data.Tags
    where tag.id == 0x10
    select new
    {
       tag.Value,
       tag.TranslatedValue
    };
return tagList.Min().TranslatedValue;

这有一个优雅的解决方案吗?

5 个答案:

答案 0 :(得分:3)

您可以使用OrderBy按升序排列元素(将最小值放在第一个位置),Select来获取翻译后的值,然后使用First来获取最小元素:

var minVal = (from data in masterList 
             from tag in data.Tags
             where tag.id == 0x10
             select tag)
             .Distinct(new TagComparer())
             .OrderBy(t => t.Value) // lowest value will be first in the list
             .First() // take the first element, which is the min
             .TranslatedValue

答案 1 :(得分:1)

您可以为标记类实现IComparable<T>,并将比较基于Value属性。然后,您可以选择最小标记,而不是选择最小标记Value

一些代码来证明我的意思:

TranslatedValue

将您的标记类设置为实现class tag : IComparable<tag> { public int Id { get; set; } public int Value { get; set; } public int TranslatedValue { get; set; } public int CompareTo(tag other) { if (other.Value > this.Value) return -1; if (other.Value < this.Value) return 1; return 0; } public override string ToString() { return string.Format("Id:{0}, Value: {1}, TranslatedValue: {2}", Id, Value, TranslatedValue); } } 。要使用它来获取IComparable<T>它就像:

一样简单
TranslatedValue

其中int minTranslatedValue = tags.Min().TranslatedValue; 是某种tags集合。

答案 2 :(得分:1)

我之前遇到这个确切问题的答案比其他人更多,但在这些情况下效果非常好,而且性能更高一些;开发一个ObjectWithMin()扩展方法,该方法将返回包含指定投影的最小值的整个对象。这是一个基本算法;它只迭代枚举一次并线性执行而不是在nlogn-time中执行:

public static T ObjectWithMin<T, TResult>(this IEnumerable<T> elements, Func<T, TResult> projection)
        where TResult : IComparable<TResult>
    {
        if (elements == null) throw new ArgumentNullException("elements", "Sequence is null.");
        if (!elements.Any()) throw new ArgumentException("Sequence contains no elements.");

        var seed = elements.Select(t => new { Object = t, Projection = projection(t) }).First();

        return elements.Aggregate(seed,
                                  (s, x) =>
                                  projection(x).CompareTo(s.Projection) < 0
                                      ? new {Object = x, Projection = projection(x)}
                                      : s
            ).Object;
    }

用法:

var tagList = 
    (from data in masterList
    from tag in data.Tags
    where tag.id == 0x10
    select new
    {
       tag.Value,
       tag.TranslatedValue
    };
return tagList.ObjectWithMin(x=>x.Value).TranslatedValue;

答案 3 :(得分:1)

答案 4 :(得分:0)

您应该可以按一个属性排序,获取第一个项目,然后获取另一个属性:

return
  masterList
  .SelectMany(data => data.Tags)
  .Where(tag => tag.id == 0x10)
  .OrderBy(tag => tag.Value)
  .First()
  .TranslatedValue;