5

次のPythonの最小/最大コードのC#と同等のものは何ですか?

pairs = [ (2,"dog"), (1, "cat"), (3, "dragon"), (1, "tiger") ]

# Returns the PAIR (not the number) that minimizes on pair[0]
min_pair = min(pairs, key=lambda pair:pair[0])

# this will return (1, 'cat'), NOT 1

C#のEnumerable.Minは非常に近いようです。ただし、MSDNのドキュメントによると、常に最小化値を返します(元のオブジェクトではありません)。私は何かが足りないのですか?

編集


注意してください-ソート(O(nlogn))は最小値(O(n))を見つけるよりも計算が重いため、最初にソートすることでこれを達成する傾向はありません。

また、注意してください-辞書も望ましいアプローチではありません。キーが重複している場合((1、 "cat")と(1、 "tiger")は処理できません。

さらに重要なことに、ディクショナリは、処理されるアイテムが複雑なクラスである場合を処理できません。たとえば、年齢をキーとして使用して、動物オブジェクトのリストから最小値を見つけます。

class Animal
{
  public string name;
  public int age;
}
4

4 に答える 4

3

BCLには MinBy 関数はありませんが、自分で簡単に作成できます。

public static T MinBy<T, C>(this IEnumerable<T> items, Func<T, C> projection) where C : IComparable<C> {
    return items.Aggregate((acc, e) => projection(acc).CompareTo(projection(e)) <= 0 ? acc : e);
}

プロジェクションの再評価を避けるために、私よりも複雑な MinBy を作成することを選択できます。いずれにせよ、MinBy 関数を取得したら、問題を簡単に解決できます。

var pairs = new[] {Tuple.Create(2,"dog"), Tuple.Create(1, "cat"), Tuple.Create(3, "dragon"), Tuple.Create(1, "tiger")};
var min_pair = pairs.MinBy(e => e.Item1);
于 2012-05-29T05:51:34.887 に答える
0

私は使うだろう

var min = pairs.OrderBy(x => x.FirstValue).FirstOrDefault();

並べ替えは最小値を見つけるよりも重いことに同意しますが、これはセット全体を並べ替えるわけではないことに注意してください。それは、セットの順序付けられた列挙の最初の(またはデフォルトの)アイテムを見つけることです-それは怠惰に繰り返されます。

あなたが持っていた場合

var min = pairs.OrderBy(x => x.FirstValue).ToList().FirstOrDefault();

それなら私は同意します-あなたはあなたのペアをソートしてから最初のものを取ります。ただし、LINQはそれよりも賢く、セットを並べ替えることはありません。注文された可能性があるがまだ実行されていないコレクションから最初のものを取得します。


Dictionary複雑なコレクション(リストなど)を使用できないという点に加えて、Animalどのように並べ替えますAnimalか?複雑なオブジェクトで並べ替えることはできません。代わりに、動物の年齢をキーとして使用する必要があります。辞書はこれを非常に簡単に行うことができます-実際、辞書のキーは辞書の値と同じになることはありません。そうでなければ、ポイントは何でしょうか?

var animals = new List<Animal>();
// get some animals...

var animalictionary = animals.ToDictionary(a => a.Age);
// assuming the animals have distinct ages, else

var animalLookup = animals.ToLookup(a => a.Age);

foreach (var animalGroup in animalLookup)
{
    var age = animalGroup.Key;
    Console.WriteLine("All these animals are " + age);
    foreach (Animal animal in animalGroup)
    {
        Console.WriteLine(animal.name);
    }
} 
于 2012-05-29T06:23:56.810 に答える
0

編集

var minage = collection.Min( x => x.Age ); //for maxage replace Min by Max
var minAgeAnimals = collection.where(x=> x.age == minage); 
foreach(Animal animal in minAgeAnimals )
   Console.Writeline (  animal.Age.ToString() + " : " + animal.Name); 

前へ 質問の編集前に回答済み

C#で辞書オブジェクトを利用し、このようなことをするよりも、あなたが望むのと同じことをします

int minimumKey = touchDictionary.Keys.Min(); 
string value = "";
touchDictionary.TryGetValue(minimumKey, out value))
Console.Writeline ( "min key pair is:-" + minimumKey.ToString() + " : " + value); 

また

linq の助けを借りて、それはあなたにとって簡単になります

var dictionary = new Dictionary<int, string>  
                     {{1, "one"}, {2, "two"}, {3, "three"}, {4, "four"}  };  

        var maxKey = dictionary.Max(x => x.Key);  
        var minkey = dictionary.Min(x => x.Key);  
于 2012-05-29T05:39:07.427 に答える
0

使用する

Dictionary<int, string> pairs = new Dictionary<int, string>()
                          { {2,"dog"}, {1, "cat"}, {3, "dragon"} };

var min = pairs.OrderBy(x => x.Key).FirstOrDefault();

また

int min = pairs.Keys.Min();

Dictionary<int, string> result 
                          = new Dictionary<int, string>() { {min, pairs[min]} };
于 2012-05-29T05:42:18.003 に答える