如何透过此对象列表?

时间:2013-07-23 10:48:14

标签: c# linq

我有Channels

的列表
var blocks = new List<Block>();
foreach (var channel in ChannelsCollection)
{
    var ch = channel.ChannelCollectionItems.Select(item => new Channel
    {
        Id = channel.Id, 
        Delay = item.Delay,
        Trigger = item.Trigger,
        Restore = item.Restore,
    }).ToList();

    blocks.Add(new Block { Id = index++ , Channels = ch});
}

这会生成一个Blocks列表,其中每个列表都包含Channels列表。

e.g。

Block1          Block2          Block3          Block4
    Channel1        Channel1        Channel1        Channel1
        Val1            Val1            Val1            Val1
        Val2            Val2            Val2            Val2
        Val3            Val3            Val3            Val3
    Channel2        Channel2        Channel2        Channel2
        Val1            Val1            Val1            Val1
        Val2            Val2            Val2            Val2
        Val3            Val3            Val3            Val3
    Channel3        Channel3        Channel3        Channel3
        Val1            Val1            Val1            Val1
        Val2            Val2            Val2            Val2
        Val3            Val3            Val3            Val3

我需要透视此列表,以便我有一个Channels列表,其中包含该频道的每个Block

e.g。

Channel1    
    Block1        Block2        Block3        
        Val1            Val1            Val1  
        Val2            Val2            Val2  
        Val3            Val3            Val3  

Channel2
    Block1        Block2        Block3        
        Val1            Val1            Val1  
        Val2            Val2            Val2  
        Val3            Val3            Val3            

Channel3
    Block1        Block2        Block3        
        Val1            Val1            Val1  
        Val2            Val2            Val2  
        Val3            Val3            Val3        

是否有快速方法(例如使用LINQ)来执行此操作?

修改

ChannelBlock定义为:

public class Channel
{
    public int? Id { get; set; }
    public string Delay { get; set; }
    public string Trigger { get; set; }
    public string Restore { get; set; }
}

public class Block
{
    public int Id { get; set; }
    public List<Channel> Channels { get; set; }
}

3 个答案:

答案 0 :(得分:2)

尝试类似

的内容
var channels = blocks
    .SelectMany(b => b.Channels.Select(c => new { b, c }))
    .GroupBy(p => p.c.Id)
    .Select(g => new { Channel = g.First().c, Blocks = g.Select(p => p.b) });

正如其他人所指出的,你的Channel类没有任何地方可以存储Block的序列,所以这会返回一个匿名对象序列,其中Channel被称为{ {1}}和名为Channel的{​​{1}}。

请注意,它还会将IEnumerable<Block>Blocks进行比较,因为它们似乎不具有可比性。如果Channel之间的Id不一致,则只需从第一个Channel获取Block

答案 1 :(得分:1)

试试这个:

var r = blocks
    .GroupBy(b => b.Channels.Select(c => c))
    .Select(g => new { Channel = g.Key, Blocks = g.Select(b1 => b1) });

答案 2 :(得分:0)

原来这是解决方案:

public class ChannelRowCell
{
    public string Name { get; set; }
    public string Delay { get; set; }
    public string Trigger { get; set; }
    public string Restore { get; set; }
}

public class ChannelRow
{
    public int Id { get; set; }
    public List<ChannelRowCell> Cells { get; set; }
}

public static class DigiChannelsExtensions
{

    public static List<ChannelRow> GetRows(this List<DigiChannelsVM> digiChannelsVms)
    {
        var blocks = (from vm in digiChannelsVms
                      let ch = vm.ChannelCollectionItems.Select(item => new 
                      {
                          vm.Id,
                          Type = item.Types.EnumDataItems.FirstOrDefault(xx => xx.IsSet).Description,
                          Delay = item.Delay.Value.ToString(),
                          Trigger = item.Trigger.Value == 0 ? "+" : "-",
                          Restore = item.Restore.GetSelectedEnumItems().FirstOrDefault().Description == "Restore" ? "Y" : "N",
                      }).ToList()
                      select new { Id = vm.Id.Value, Channels = ch }).ToList();

        var channelRows = new List<ChannelRow>();
        //for (var i = 0; i < blocks[0].Channels.Count; i++)
        for (var i = 0; i < blocks[0].Channels.Count; i++)
        {
            var channelRow = new ChannelRow { Cells = new List<ChannelRowCell>(), Id = i+1 };
            foreach (var cc in blocks.Select(block => block.Channels[i]))
            {
                channelRow.Cells.Add(new ChannelRowCell
                {
                    Delay = cc.Delay,
                    Name = cc.Type,
                    Restore = cc.Restore,
                    Trigger = cc.Trigger,
                });
            }

            channelRows.Add(channelRow);
        }

        return channelRows;
    }
}