在数组的子集中查找min值的优雅方法是什么?

时间:2012-05-26 02:01:26

标签: c# arrays

我有一个100个整数的数组a。建议的方法是在a[3]a[70] 中查找最小值以及此最小值的索引?假设没有重复值。

我知道循环通过相关指数范围的笨拙方式:

for(i = 3; i < 70, i++) 
{
    ...
}

我正在寻找一种更优雅的方式在C#中执行此操作而不是循环。感谢。

3 个答案:

答案 0 :(得分:6)

找出分钟

List<int> templist = a.Skip(3).Take(67).ToList();

int minimum = templist.Min();

索引

int index = templist.FindIndex(i => i == minimum) + 3;

我添加了3,因为列表中的索引比原始序列a中的索引少3。

它在做什么

  1. 跳过 - 留下前3个值,即索引0,1,2并返回剩余的数组。
  2. Take - 从Skip返回的数组中获取67个值。 (因为你的for循环从3开始直到70,所以你基本上循环67项bcoz 70 - 3 = 67)。
  3. ToList - 将返回的序列转换为List以查找索引。
  4. Min - 从中​​获取最小值。
  5. 你必须使用循环,因为它是一个序列。因为你说优雅而不是for循环我使用LINQ(即使它也循环也)。

答案 1 :(得分:3)

如果您的数据结构没有排序,那么如果没有循环遍历子列表中的所有元素,则无法通过提供的API使用某些隐式循环来执行此操作。

您不能使用已排序的集合,因为您正在处理它的子部分(因此您需要为列表的部分创建一个已排序的集合),所以无论如何您都必须循环在它上面。

答案 2 :(得分:1)

LINQ的Aggregate并不是最简单的,但它可以说是“优雅”解决方案中效率最低的(尽管它们仍然比简单的循环更多的代码行。另外,迭代自己仍然是最好的,因为你没有分配任何额外的内存。)

但无论如何,如果你觉得有必要让你的继任者把你挂在肖像中,你可以做到这一点,而不是一个简单的循环:

var minValueAndItsIndex = a
.Skip(3)
.Take(70 - 3)
.Select((value, index) => new { Value = value, Index = index + 3})
.Aggregate((tuple1, tuple2) => (tuple1.Value < tuple2.Value) ? tuple1 : tuple2);

如果您创建一个基于2项ValueType的元组并使用它而不是匿名类型,它将与更有效的直接迭代相比,因为它不会分配任何额外的内存。