return different lists for each key

孤街醉人 提交于 2019-12-13 04:24:15

问题


I have a table that is parsed in code as a List of string[] (each string[] is a column).

Column1| Column2  | Column3
--------+---------+----------
0       | 1       | 8
3       | 2       | 3
5       | 2       | 8

Let´s say:

string[] column1 = { 0, 3, 5 }
string[] column2 = { 1, 2, 2 };
string[] column3 = { 8, 3, 8 };
List<string[]> table = new List<string[]>() { column1, column2, column3 };

I want to select a column (i.e. Column1) groupby Column3, and create a list with each different value in Column3. In other words: group Column1 by column3 and create a Column for each different value of Column3.

The output would be:

string[] result1 = { 3 };  // From column3[1] = 3
string[] result2 = { 0, 5 };  // From column3[0] = column3[2] = 8

It´s a mix of this post, this one, and Simple 1 from msdn. I think about creating a object with column1 and column3, and then do as this 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());

But this code code is a bit ugly. Isn´t there something like

column3.selectmany(...).GroupBy(row => row.row3).ToDictionary(grp => grp.Key, grp => grp.ToList());

I mean, some expression without the need of creating a new class and fill a list of objects... Also, I want as output

string[] result1 = { 3 };  // From column3[1] = 3
string[] result2 = { 0, 5 };  // From column3[0] = column3[2] = 8

回答1:


Instead of creating a new type just for grouping you can use the Zip extension method and an anonymous type to create the rows.

Grouping is pretty straightforward then. Each group has a key which represents column3 and the IGrouping itself is an IEnumerable containing the rows from which you select only column 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();

This produces an IEnumerable<string[]>.




回答2:


pescolino's answer using Zip is quite nice. If you can't use it (e.g. if you are not on .NET 4.x) then you could use the indexer-overload of Select to produce the desired result:

var res = col1.Select((fld,idx) => new { Field = fld, Index = idx })
          .GroupBy(entry => col3[entry.Index], entry => entry.Field)
          .Select(grp => grp.ToArray());


来源:https://stackoverflow.com/questions/15214204/return-different-lists-for-each-key

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!