我有一个List<List<double>>
,我需要找到一个List MyList,其中MyList [0]例如是List的所有第一个元素的Max。
例子,只是为了清楚:
第一个列表包含(3,5,1),第二个包含(5,1,8),第三个包含(3,3,3),第四个包含(2,0,4)。
我需要找到一个列表(5,5,8)。
我不需要清单(5,8,3,4)。
当然我知道如何使用嵌套for循环来完成它。 我想知道是否有一种linq方式并且相信我,我不知道从哪里开始。
答案 0 :(得分:4)
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);
}
答案 1 :(得分:2)
试试这个:
// 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());
}
注意:此解决方案仅在列表中包含的所有列表具有相同数量的元素时才有效。
答案 2 :(得分:0)
如果你总是知道列表中有多少元素,你可以使用这种方法:
var result = new[]
{
list.Select(a => a[0]).Max(),
list.Select(a => a[1]).Max(),
list.Select(a => a[2]).Max()
};
答案 3 :(得分:0)
即使很久以前就回答了这个话题,我也想在这里提出另一个我用Linq编写的解决方案,比other solution更短:
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,...)。