2

私は.net 3.5が初めてです。私はアイテムのコレクションを持っています:

IList<Model> models;

どこ

class Model
{
    public string Name
    {
       get;
       private set;
    }
}

名前の長さが最も長い要素を取得したいと思います。私は試した

string maxItem = models.Max<Model>(model => model.Name.Length);

もちろん、最大長を返します(Modelオブジェクトが必要です)。拡張メソッドを使用してこれを行う方法があることは知っていますが、その方法はわかりません。

4

6 に答える 6

7

残念ながら、これを行う組み込みの方法はありませんが、それを行うための拡張メソッドを作成するのは非常に簡単です。

それは私の最初のブログ投稿の 1 つにありました。実際、コメントの 1 つに、より良い実装があることに注意してください。時間があれば体内に移します。

編集:わかりました、少し省略されたバージョンがあります-指定されたセレクターを使用して、最大の要素を返すだけです。プロジェクションも行う必要はありません - 必要に応じて後で一度行ってください。制約を削除して代わりに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;
于 2008-12-21T16:44:11.683 に答える
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;

これには多くの余分な割り当てが必要ですが、学術的には興味深いものです (私はそう思います)。

于 2008-12-21T17:42:16.633 に答える
0

集計を使用できます。新しい拡張メソッドを書かなくてもできます。

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);
于 2008-12-21T19:24:51.390 に答える
0

拡張メソッドを使用することで得られるものはありますか?

おそらく、リストの単純な反復を伴うメソッドまたは手順で十分でしょうか?

効果のあるもの

文字列として薄暗い結果 = models(0).Name
モデル内のモデルとしての各 m
  m.Name.length > result.length の場合
    結果 = m.Name
  終了する場合
次
于 2008-12-21T17:08:31.743 に答える
0

これが私がそれを機能させる方法です。たぶんもっと良い方法があるかもしれませんが、私にはわかりません:

    decimal de = d.Max(p => p.Name.Length);
    Model a = d.First(p => p.Name.Length == de);
于 2008-12-21T16:50:28.860 に答える
-1

別の方法は次のとおりです。

var item = (from m in models select m orderby m.Name.Length descending).FirstOrDefault(); 

最初のものは、最も長いものになります。

于 2008-12-21T17:10:34.843 に答える