我正在使用列表(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
类包含字段Id
,Value
和TranslatedValue
。我想根据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;
这有一个优雅的解决方案吗?
答案 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;