2016-11-05 64 views
1

我有類篩選列表Occurence明智的閱讀C#

public class RoomDetails 
    { 
    public int RoomIndexID {get;set;} --(This is No of Rooms) 
    public int roomcategoryID {get;set;} -- (This is No of Category that room have) 
    public decimal roomPrice{get;set;} 
    public string roomCategory{get;set;} 
    } 

所以我有這樣的(數據)RoomDetails名單

  • 1,1,200,單人牀
  • 2,1,250,雙牀
  • 2,2,400,加大牀雙人牀
  • 2,4,530,三人牀
  • 3,1,530,TRIPPLE牀
  • 3,2,600,三人間大牀

,所以我想讀這個列表下面的過程。

  • 1,1,200,單人牀
  • 2,1,250,雙人牀
  • 3,1,530,TRIPPLE牀

  • 1,1,200,單人牀
  • 2,1,250,雙人牀
  • 3,2,600,三人大牀

  • 1,1,200,單人牀
  • 2,2,400,帶一張雙人牀和額外操作
  • 3,1,530,TRIPPLE牀

  • 1, 1,200,單人牀
  • 2,2,400,雙人牀與額外操作
  • 3,2,600,三人間大牀

  • 1,1,200,單人牀
  • 2,4,530,TRIPPLE牀
  • 3,1,530,TRIPPLE牀

  • 1,1,200,單人牀
  • 2,4,530,TRIPPLE牀
  • 3,2,600,三人間大牀

請問你是否有改編職系我的問題任何問題。

這是示例

我的數據列表是這樣

  • 間A - A1
  • 室B - B1,B2,B3
  • 室C - C1,C2

(實際上A,B,C表示RoomIndexID的和A1,B1,B2,B3,C1,C2是roomcategoryID的) 所以想要REA像這樣。

  • A1,B1,C1
  • A1,B1,C2
  • A1,B2,C1
  • A1,B2,C2
  • A1,B3,C1
  • A1,B3, C2
+0

你想分組什麼?我沒有看到在任何列表 –

+0

任何連接有RoomIndexID.1.2,3智慧。並有roomcategoryID。 可以說第一個房間1,1,200,單人牀如果同一房間指數有另一個房間那麼它將像1,2,200,單人牀 我不想group.i想讀一下這個列表RoomIndexID和roomcategoryID的一些mecanism的基礎。我將添加示例示例。 – TNO

回答

0

如果你想要「LINQy」解決方案,它會有點複雜。請注意,這是LINQ來反對,所以如果您有IQueryable(例如來自EntityFramework),您將需要先致電.ToList()

var total = list.GroupBy(x=>x.RoomIndexID) 
    .Select(x=>x.Count()) 
    .Aggregate(1, (s,d)=>s*d); 

var counts = list.GroupBy(x => x.RoomIndexID) 
    .ToDictionary(x => x.Key, x => x.Count()); 

var nums = list.GroupBy(x => x.RoomIndexID) 
    .Select(x => x.Select((p, i) => new {i, p})) 
    .SelectMany(x => x) 
    .ToList(); 

var result = Enumerable.Range(0, total) 
    .Select(x => 
     nums.Where(y => {    
      var c = counts[y.p.RoomIndexID]; 
      var p = counts 
         .Where(z => z.Key > y.p.RoomIndexID) 
         .Aggregate(1, (s,d)=>s*d.Value); 

      return y.i == x/p%c; 
     }) 
     .Select(y => y.p) 
    ); 

演示在這裏:https://dotnetfiddle.net/udf6VA

+0

感謝您的幫助。這個代碼完美地完成了這項工作... 但它太複雜了。請給我一些關於這段代碼的解釋嗎? – TNO

0

簡單了很多,像這樣的事:

var groups = list // your input 
    .GroupBy(x => x.RoomIndexID) 
    .Select(x => x.ToList()) 
    .ToList(); 

var result = groups.Skip(1).Aggregate(
    groups.Take(1), 
    (x, y) => x.SelectMany(z => y, (a, b) => a.Concat(new[] { b }).ToList())); 

基本思路是先GroupBy房指數,讓你得到相同類型的內部序列,然後在這些序列之間執行交叉連接(SelectMany可以),最後加入Aggregate加入的結果。這三個步驟應該沒問題。

var groups = list 
    .GroupBy(x => x.RoomIndexID) 
    .Select(x => x.ToList()); 

IEnumerable<IEnumerable<RoomDetails>> result = null; 
foreach (var item in groups) 
{ 
    if (result == null) 
     result = new[] { item }; 
    else 
     result = result.SelectMany(x => item, (x, y) => x.Concat(new[] { y })); 
} 

這件事情本來可以做一步到位了,我們有一個適當的過載Aggregate這需要第一項的Func序列中作爲種子:參與可以更加清楚以下命令行式風格中的步驟。

// Say you have: 
public static TAccumulate Aggregate<TSource, TAccumulate>(
    this IEnumerable<TSource> source, 
    Func<TSource, TAccumulate> seeder, 
    Func<TAccumulate, TSource, TAccumulate> func) 
{ 
    if (source == null) 
     throw new ArgumentNullException(nameof(source)); 

    if (func == null) 
     throw new ArgumentNullException(nameof(func)); 

    using (IEnumerator<TSource> iterator = source.GetEnumerator()) 
    { 
     if (!iterator.MoveNext()) 
      throw new InvalidOperationException("Empty sequence."); 

     TAccumulate result = seeder(iterator.Current); 
     while (iterator.MoveNext()) 
     { 
      result = func(result, iterator.Current); 
     } 

     return result; 
    } 
} 

// Then you could do: 
var result = list 
    .GroupBy(x => x.RoomIndexID) 
    .Select(x => x.ToList()) 
    .Aggregate(
     x => Enumerable.Repeat(x, 1), 
     (x, y) => x.SelectMany(z => y, (a, b) => a.Concat(new[] { b }).ToList())); 

這整個事情看起來很複雜,因爲在框架或語言中有一些缺失的部分。理想情況下(以及我假設的許多功能語言)你應該可以這樣做:

var result = list 
    .GroupBy(x => x.RoomIndexID) 
    .Aggregate(x => x.Yield(), (x, y) => x.SelectMany(z => y, (a, b) => a.Append(b)));