在不可数项目中的子组中运行项目数

时间:2014-10-16 16:01:16

标签: c# .net linq f# functional-programming

说我有一个

IEnumerable< IEnumerable< string > > rowsOfTextColumns

内部可发生的字符串值表示行中的列,因此外部的ienumerable存储多行文本列。 喜欢:3行乘4列:

12345    foo    2014-10-16 09:55    blah
12345    foo    2014-10-16 09:55    bleh
67890    bar    2014-10-16 09:58    ugh

DateTime列值不是唯一的 - 正如您在示例中所见,可以同时显示多个条目。但是datetime最适合在我的数据中用作ID。 由于我想为每一行添加一个唯一的ID,我想在每一行中添加一个列&#34;动态&#34;,其中包含具有相同日期时间的条目的出现次数,从1开始。像这样:

12345     foo     2014-10-16 09:55    blah    (1)
12345     foo     2014-10-16 09:55    bleh    (2)
67890     bar     2014-10-16 10:21    ugh     (1)

(澄清:唯一ID是日期时间+日期时间子组内运行数的复合)

当然我知道怎么做一些方式。 但是 - 如何最优雅地完成,例如使用C#的LINQ /函数编程方面? 此外,我很好奇,在F#中如何做到最优雅呢?

编辑#1:更好地说明了源数据格式

编辑#2: 好吧,在一条评论中建议使用groupby,到目前为止我得到了这个(在C#中,看看我选择的F#代码答案):

var groupsByDatetime = rowsOfColumns.GroupBy( rec => rec.ElementAt(2) );
var extendedRows =
    groupsByDatetime.SelectMany( g =>
        g.Select( (columns,i) =>
            columns.Concat( new[]{(1+i).ToString()} ) ) );                  

有人出价? :) 我猜,我看起来并不太糟糕。

1 个答案:

答案 0 :(得分:1)

这会对项目进行分组并映射每个项目,以便在组中包含其索引。

let groupAndIndexItems keySelector =
    Seq.groupBy keySelector
    >> Seq.map (fun (key, items) -> 
        let indexedItems = items |> Seq.mapi (fun i x -> x, i)
        key, indexedItems
    )

使用示例:

[
    12345, "foo", "2014-10-16 09:55", "blah"
    12345, "foo", "2014-10-16 09:55", "bleh"
    67890, "bar", "2014-10-16 09:58", "ugh"
]
|> groupAndIndexItems (fun (_, _, s, _) -> s)

输出:

val it : seq<string * seq<(int * string * string * string) * int>> =
  seq
    [("2014-10-16 09:55",
      seq [((12345, "foo", "2014-10-16 09:55", "blah"), 0);
           ((12345, "foo", "2014-10-16 09:55", "bleh"), 1)]);
     ("2014-10-16 09:58", 
      seq [((67890, "bar", "2014-10-16 09:58", "ugh"), 0)])]