2014-02-11 83 views
1

我不确定这是否可能。 我的班级我有这样看起来的列表:按照包含元素的日期排序组(LINQ)

class Person 
{ 
string Firstname 
string Lastname 
DateTime Timestamp 
} 

现在我想通过创建组

  • 约翰迪尔,3:12
  • 约翰迪尔,6:34
  • 约翰迪尔,11:12
  • 汤健,1:12
  • 汤健,3:49
  • 汤健,4:22
  • 马库斯·费尔,11:23

进一步,我想到排序这个群组由他们的时间戳,最后应该是第一个,而组应该停留在列表视图中显示他们

  • 马库斯·费尔(组头)
    11:23(内容元素)

  • 约翰迪尔
    11:12
    6:34

  • 汤健
    4: 22
    3:49

  • 约翰迪尔
    3:12

  • 汤健
    1:22

希望任何Linq的天才可以帮助我解决这个问题:) 谢谢!


非常感谢谢尔盖,工作就像一个魅力!

此外,我想为我的组键创建一个自定义类,以在我的ListView标题中显示不同的附加内容。 (不仅是拼接在一起字符串)

我想我的查询分配给一个IEnumerable这样的:

IEnumerable<IGrouping<Header, Person>> PersonGroups 

其中报头包含有对每个人(其他一些特性如存在也是一个国家,年龄,...每个人)。也许你也可以帮助我呢?


再次感谢谢尔盖。通过实现一个实现ICompareable接口的Header类来解决我的问题。

IEnumerable<IGrouping<Header, Person>> PersonGroups 

public class Header: IComparable<Header> 
{ 
    public Header(string firstname, string lastname) 
    { 
     Firstname= firstname; 
     Lastname = lastname; 
    } 

    public string Firstname{ get; set; } 
    public string Lastname{ get; set; } 

    public int CompareTo(Header that) 
    { 
     if (this.Firstname == that.Firstname&& this.Lastname == that.Lastname) 
      return 0; 
     else 
      return -1; 
    } 
    } 

我的查询现在看起来是这样的:

PersonGroups= persons.OrderByDescending(p => p.Timestamp) 
       .GroupConsecutive(p => new Header(p.Firstname, p.Lastname)); 

回答

1

其实你需要首先命令由时间戳结果。才把这个组有序序列由连续的人们:

var query = 
    people.OrderByDescending(p => p.Timestamp.TimeOfDay) 
     .GroupConsecutive(p => String.Format("{0} {1}", p.Firstname, p.Lastname)) 
     .Select(g => new { 
      Header = g.Key, 
      Content = String.Join("\n", g.Select(p => p.Timestamp.TimeOfDay)) 
     }); 

您需要GroupConsecutive实施的基础上,(在你的案件的全名)提供选择的相同值连续创建项目组。

为您的样品输入的结果是:

[ 
    { 
    "Header": "Markus Fert", 
    "Content": "11:23:00" 
    }, 
    { 
    "Header": "John Deer", 
    "Content": "11:12:00\n06:34:00" 
    }, 
    { 
    "Header": "Tom Kin", 
    "Content": "04:22:00\n03:49:00" 
    }, 
    { 
    "Header": "John Deer", 
    "Content": "03:12:00" 
    }, 
    { 
    "Header": "Tom Kin", 
    "Content": "01:12:00" 
    } 
] 
+1

哇,这绝对是伟大的!谢谢谢尔盖,像一个魅力,我现在得到了我所需的团体。 我还有一个问题 - 编辑我的问题。也许你也可以帮助我呢?但是非常感谢你! – sust86

+1

@ sust86如果你想'IGrouping '而不是'IGrouping '那么就让你的Header类实现IComparable - 它是默认比较器比较分组键所必需的 –

+1

Nevermind,纠正了错误我的人际关系组成员。谢谢 ! – sust86

0

下面是使用的方法的内置链接运营商Aggregate

首先,我需要通过降序时间戳来排序,然后我创建了一个名称格式化函数。

var op = people 
    .OrderByDescending(p => p.Timestamp) 
    .ToArray(); 

Func<Person, string> toName = p => 
    String.Format("{0} {1}", p.Firstname, p.Lastname); 

现在我可以构建查询:

var query = 
    op 
     .Skip(1) 
     .Aggregate(new [] 
     { 
      new 
      { 
       Name = toName(op.First()), 
       Timestamps = new List<string>() 
       { 
        op.First().Timestamp.ToShortTimeString(), 
       }, 
      }, 
     }.ToList(), (a, p) => 
     { 
      var name = toName(p); 
      if (name == a.Last().Name) 
      { 
       a.Last().Timestamps.Add(p.Timestamp.ToShortTimeString()); 
      } 
      else 
      { 
       a.Add(new 
       { 
        Name = name, 
        Timestamps = new List<string>() 
        { 
         p.Timestamp.ToShortTimeString(), 
        }, 
       }); 
      } 
      return a; 
     }); 

我得到了这样的结果:

result