我是.net 3.5的新手。 我收集了一些物品:
IList<Model> models;
,其中
class Model
{
public string Name
{
get;
private set;
}
}
我想获得名称长度最长的元素。 我试过了
string maxItem = models.Max<Model>(model => model.Name.Length);
但它当然会返回最大长度(我需要一个Model
个对象)。我知道有一种方法可以使用扩展方法,但我不知道如何。
答案 0 :(得分:7)
遗憾的是,没有内置的方法可以做到这一点 - 但是编写扩展方法很容易。
实际上是在one of my very first blog posts中......请注意,其中一条评论中有更好的实施方式。如果我有时间,我会把它移到身体里。
编辑:好的,我有一个略有缩写的版本 - 它只是使用给定的选择器返回最大元素。也不需要进行投影 - 如果需要,可以在之后做一次。请注意,您可以删除TValue
上的约束并改为使用Comparer<TValue>.Default
,或者使用重载来允许将比较指定为另一个参数。
public static TSource MaxBy<TSource, TValue>(this IEnumerable<TSource> source,
Func<TSource, TValue> selector)
where TValue : IComparable<TValue>
{
TValue maxValue = default(TValue);
TSource maxElement = default(TSource);
bool gotAny = false;
foreach (TSource sourceValue in source)
{
TValue value = selector(sourceValue);
if (!gotAny || value.CompareTo(maxValue) > 0)
{
maxValue = value;
maxElement = sourceValue;
gotAny = true;
}
}
if (!gotAny)
{
throw new InvalidOperationException("source is empty");
}
return maxElement;
}
样本使用:(注意类型推断):
string maxName = models.MaxBy(model => model.Name.Length).Name;
答案 1 :(得分:1)
这是另一种做法。 Max
的版本不采用任何标准,并使用IComparable
。因此,我们可以提供一种方法来在可比对象中包装任何内容,并使用委托提供比较。
public class Comparable<T> : IComparable<Comparable<T>>
{
private readonly T _value;
private readonly Func<T, T, int> _compare;
public Comparable(T v, Func<T, T, int> compare)
{
_value = v;
_compare = compare;
}
public T Value { get { return _value; } }
public int CompareTo(Comparable<T> other)
{
return _compare(_value, other._value);
}
}
然后我们可以说:
Model maxModel = models.Select(m => new Comparable<Model>(m, (a, b) => a.Name.Length - b.Name.Length)).Max().Value;
这涉及很多额外的分配,但它在学术上很有意思(我认为)。
答案 2 :(得分:0)
这就是我开始工作的方式。也许有更好的方法,我不确定:
decimal de = d.Max(p => p.Name.Length);
Model a = d.First(p => p.Name.Length == de);
答案 3 :(得分:0)
使用扩展方法有什么好处吗?
使用列表的简单迭代的方法或过程可能就足够了吗?
的影响
Dim result as string = models(0).Name for each m as Model in models if m.Name.length > result.length then result = m.Name end if next
答案 4 :(得分:0)
您可以使用Aggregate。无需编写新的扩展方法即可完成。
models.Aggregate(
new KeyValuePair<Model, int>(),
(a, b) => (a.Value < b.Name.Length) ? new KeyValuePair<Model, int>(b, b.Name.Length) : a,
a => a.Key);
答案 5 :(得分:-1)
另一种方式可能是:
var item = (from m in models select m orderby m.Name.Length descending).FirstOrDefault();
第一个将是长度最长的那个。