我有一个在代码中解析为String []的列表(每个字符串[]都是一列)。
Column1| Column2 | Column3
--------+---------+----------
0 | 1 | 8
3 | 2 | 3
5 | 2 | 8
我们说:
string[] column1 = { 0, 3, 5 }
string[] column2 = { 1, 2, 2 };
string[] column3 = { 8, 3, 8 };
List<string[]> table = new List<string[]>() { column1, column2, column3 };
我想通过Column3选择一个列(即Column1)组,并在Column3中创建一个包含每个不同值的列表。换句话说:按列3对Column1进行分组,并为Column3的每个不同值创建一个列。
输出结果为:
string[] result1 = { 3 }; // From column3[1] = 3
string[] result2 = { 0, 5 }; // From column3[0] = column3[2] = 8
这是post,one和msdn中的简单1的混合。 我考虑使用column1和column3创建一个对象,然后执行此post:
Class Row { public Row(string row1, string row3); }
List<Row> rows = new List<Row>();
for(int i = 0; i < column1.Length; i++)
{ rows.Add(new Row(Column1[i], Column3[i])); }
var output = rows.GroupBy(row => row.row3).ToDictionary(grp => grp.Key, grp => grp.ToList());
但是这段代码有点难看。是不是像
那样column3.selectmany(...).GroupBy(row => row.row3).ToDictionary(grp => grp.Key, grp => grp.ToList());
我的意思是,一些表达式无需创建新类并填充对象列表...另外,我想作为输出
string[] result1 = { 3 }; // From column3[1] = 3
string[] result2 = { 0, 5 }; // From column3[0] = column3[2] = 8
答案 0 :(得分:1)
您可以使用Zip
扩展方法和anonymous type
来创建行,而不是仅为分组创建新类型。
分组非常简单。每个组都有一个代表column3的键,而IGrouping
本身就是一个IEnumerable
,其中包含您只从中选择第1列的行:
var rows = column1.Zip(column3, (c1, c3) => new
{
Column1 = c1,
Column3 = c3
});
var output = from row in rows
group row by row.Column3 into groupedRows
select groupedRows.Select(r => r.Column1).ToArray();
这会产生IEnumerable<string[]>
。
答案 1 :(得分:0)
pescolino使用Zip
的答案非常好。如果你不能使用它(例如,如果你不在.NET 4.x上)那么你可以使用Select
的索引器重载来产生所需的结果:
var res = col1.Select((fld,idx) => new { Field = fld, Index = idx })
.GroupBy(entry => col3[entry.Index], entry => entry.Field)
.Select(grp => grp.ToArray());