我有一个List<List<double>>
,我需要找到一个列表MyList,例如MyList[0]是列表中所有第一个元素的最大值。举个例子,说明一下:第一个列表包含(3,5,1),第二个包含(5,1,8),第三个包含(3,3,3),第四个包含(2,0,4)。我需要找到一个包含(5,5,8)的列表。我不需要列表(5,8,3,4)。
我当然知道如何使用嵌套for循环。我想知道是否有一个linq方法,相信我,我不知道从哪里开始。
var source = new List<List<int>> {
new List<int> { 3, 5, 1 },
new List<int> { 5, 1, 8 },
new List<int> { 3, 3, 3 },
new List<int> { 2, 0, 4 }
};
var maxes = source.SelectMany(x => x.Select((v, i) => new { v, i }))
.GroupBy(x => x.i, x => x.v)
.OrderBy(g => g.Key)
.Select(g => g.Max())
.ToList();
返回{ 5, 5, 8}
,这是您需要的。并且当源列表有不同数量的元素时也可以工作。
如果你也需要Min
的版本,并希望防止代码重复,你可以去一点功能:
private static IEnumerable<TSource> GetByIndex<TSource>(IEnumerable<IEnumerable<TSource>> source, Func<IEnumerable<TSource>, TSource> selector)
{
return source.SelectMany(x => x.Select((v, i) => new { v, i }))
.GroupBy(x => x.i, x => x.v)
.OrderBy(g => g.Key)
.Select(g => selector(g));
}
public static IEnumerable<TSource> GetMaxByIndex<TSource>(IEnumerable<IEnumerable<TSource>> source)
{
return GetByIndex(source, Enumerable.Max);
}
public static IEnumerable<TSource> GetMinByIndex<TSource>(IEnumerable<IEnumerable<TSource>> source)
{
return GetByIndex(source, Enumerable.Min);
}
试试这个:
// Here I declare your initial list.
List<List<double>> list = new List<List<double>>()
{
new List<double>(){3,5,1},
new List<double>(){5,1,8},
new List<double>(){3,3,3},
new List<double>(){2,0,4},
};
// That would be the list, which will hold the maxs.
List<double> result = new List<double>();
// Find the maximum for the i-st element of all the lists in the list and add it
// to the result.
for (int i = 0; i < list[0].Count-1; i++)
{
result.Add(list.Select(x => x[i]).Max());
}
注意:此解决方案仅适用于当列表中包含的所有列表具有相同数量的元素时。
即使这个话题很久以前就回答了,我想把我用Linq编的另一个解决方案放在这里,比这个解决方案短:
List<List<int>> mylist; //initial list of list
List<List<int>> mins_list = mylist.Aggregate(
(x, cur) => cur.Zip(x, (a, b) => (a.Value > b.Value) ? a : b).ToList()
).ToList();
这段非常简单的代码只是将每个子列表聚合成一个最小值列表。注意,内部ToList
是强制性的,因为Zip
是延迟的。
您可以将代码封装在扩展方法中,并执行与MarcinJuraszek相同的技巧来生成其他类似的计算(min, max, mean, std,…)。
如果您总是知道列表中有多少元素,您可以使用以下方法:
var result = new[]
{
list.Select(a => a[0]).Max(),
list.Select(a => a[1]).Max(),
list.Select(a => a[2]).Max()
};