2014-02-11 77 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