2

I have a list of 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});
}

This results in a list of Blocks, each of which contains a list of 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

I need to pivot this list so that I have a list of Channels that contain each Block for that channel.

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        

Is there a quick way, (e.g. with LINQ) to do this?

Edit

Channel and Block are defined as:

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; }
}
5
  • 1
    Could you post your Channel and your Block class? Commented Jul 23, 2013 at 10:49
  • 1
    Is Channel have a Block Collection property? Commented Jul 23, 2013 at 10:53
  • ChannelCollectionItems? Commented Jul 23, 2013 at 10:53
  • Where could we store the Block in the Channel? Also, what's ChannelCollectionItems? It isn't in your channel definition... Commented Jul 23, 2013 at 10:54
  • 1
    What is index++, i don't see this variable? Commented Jul 23, 2013 at 10:55

3 Answers 3

2

Try something like

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) });

As others have pointed out, your Channel class doesn't have anywhere to store a sequence of Blocks, so this returns a sequence of anonymous objects with a Channel called Channel and an IEnumerable<Block> called Blocks.

Note that it also compares Channels by Id, since they don't appear to be comparable otherwise. If your Channels are inconsistent between Blocks, this just takes the Channel from the first Block.

Sign up to request clarification or add additional context in comments.

Comments

1

Try this:

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

1 Comment

I'm not sure this is what you want - it's roughly analagous to var r = blocks.Select(b => new { Channel = b.Channels.AsEnumerable(), Blocks = Enumerable.Repeat(b, 1) });
0

This turned out to be the solution:

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;
    }
}

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.