2016-11-05 75 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)));