0

I have a this complex 3D structure of List<List<List<myClass>>> and I want it to reduced to List<List<myClass>>.

public class MyClass
{
    public string Key { get; set; }
    public decimal Price { get; set; }
}

The problem is that the MyClass is been duplicated in the origin 3D lists with the same key like:

(I'm having trouble to write 3D and 2D multi-dimensional array so I just hard coded an example.)

List<List<List<MyClass>>> level1 = new List<List<List<MyClass>>>();

List<List<MyClass>> level2_1 = new List<List<MyClass>>();
List<MyClass> level3_1 = new List<MyClass>()
{
    new MyClass() { Key = "key1", Price = 10 }
    new MyClass() { Key = "key2", Price = 20 }
};

level2_1.Add(level3_1);

List<List<MyClass>> level2_2 = new List<List<MyClass>>();
List<MyClass> level3_2 = new List<MyClass>()
{
    new MyClass() { Key = "key2", Price = 10 }
    new MyClass() { Key = "key3", Price = 20 }
};

level2_2.Add(level3_2);

I need the converted list will be like:

List<List<MyClass>> level1 = new List<List<MyClass>>();

List<MyClass> level2_1 = new List<MyClass>()
{
    new MyClass() { Key = "key1", Price = 10 }
}

List<MyClass> level2_2 = new List<MyClass>()
{
    new MyClass() { Key = "key2", Price = 10 },
    new MyClass() { Key = "key2", Price = 20 }
}

List<MyClass> level2_3 = new List<MyClass>()
{
    new MyClass() { Key = "key3", Price = 20 }
}    

level1.Add(level2_1);
level1.Add(level2_2);
level1.Add(level2_3);

So the main list is distinct by the Key and the child list to be duplicated by its Prices.

Note that Iv'e looked through these question: 1, 2, 3,

Any other elegant way achieving this? maybe linq?

Shahar Shokrani
  • 7,598
  • 9
  • 48
  • 91

2 Answers2

2

Try select many

    public static List<List<MyClass>> MyConvertLinq(List<List<List<MyClass>>> items)
    {
        var allItems = items.SelectMany(m => m).ToList();
        return allItems;
    }

--- Edit ---

you can use a GroupBy to build Groups

public static List<List<MyClass>> MyConvertLinq(List<List<List<MyClass>>> items)
    {
        var allItems = items.SelectMany(m => m).ToList().SelectMany(m => m).ToList();
        var sortedItems = allItems.GroupBy(m => m.Key, m => m,
            (k, classes) => classes.ToList()).ToList();

        return sortedItems;
    }
Daniel W.
  • 938
  • 8
  • 21
0

The best solution I was able to think of:

public List<List<MyClass>> MyConvert(List<List<List<MyClass>>> items)
{
    Dictionary<string, List<MyClass>> resultsDic = new Dictionary<string, List<MyClass>>();
    foreach (List<List<MyClass>> item in items)
    {
        foreach (List<MyClass> innerItem in item)
        {
            foreach (MyClass myClass in innerItem)
            {
                if (!resultsDic.ContainsKey(myClass.Key))
                {
                    resultsDic.Add(myClass.Key, innerItem);
                }
            }
        }

    }
    List<List<MyClass>> convertedResults = resultsDic.Select(x => x.Value).ToList();
    return convertedResults;
}
Shahar Shokrani
  • 7,598
  • 9
  • 48
  • 91