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 doc,它总是返回最小化 VALUE (不是原始对象)。我错过了什么吗?

编辑


请注意- 我不倾向于通过首先排序来实现这一点,因为排序 (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 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 回答
0

我会用

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

虽然我同意排序比找到最小值更重,但请注意这不是对整个集合进行排序。它在集合上的有序枚举中找到第一个(或默认)项 - 这是惰性迭代的。

如果你有

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

那么我同意-您正在对您的配对进行排序,然后拿走第一对。但是 LINQ 比这更聪明,而且您不会对集合进行排序。您将从可能已订购但尚未执行的集合中获取第一个。


除了您关于Dictionary无法使用复杂集合的观点(例如列表)之外,Animal您将如何按 排序Animal?您永远无法按复杂对象排序。相反,您需要使用动物的年龄作为键。Dictionary 可以很容易地做到这一点——事实上,Dictionary 的键永远不会与 Dictionary 的值相同,否则有什么意义呢?

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 回答