-4

I have the following code:

public class DataClass
{
  public int Number1 {get; set;}
  public int Number2 {get; set;}
}

List<DataClass> list = new List<DataClass>();
list.Add(new DataClass {Number1= 1, Number2 = 100});
list.Add(new DataClass {Number1= 2, Number2 = 100});
list.Add(new DataClass {Number1= 3, Number2 = 101});
list.Add(new DataClass {Number1= 4, Number2 = 102});
list.Add(new DataClass {Number1= 5, Number2 = 103});
list.Add(new DataClass {Number1= 6, Number2 = 104});
list.Add(new DataClass {Number1= 7, Number2 = 104});    

As you can see, I have a duplicate values for Number2 (i.e., two DataClass objects with Number2 set to 100, and two set to 104). I want to generate a dictionary like the one below which excludes these duplicates:

Key = 1, value = {Number1 = 1, Number2 = 100}
                 {Number1 = 3, Number2 = 101}
                 {Number1 = 4, Number2 = 102}
                 {Number1 = 5, Number2 = 103}
                 {Number1 = 6, Number2 = 104}

Key = 2, value = {Number1 = 2, Number2 = 100}
                 {Number1 = 7, Number2 = 104}

I would like to receive an optimal algorithm for solving this.

Jeremy Caney
  • 7,102
  • 69
  • 48
  • 77
Song
  • 11
  • 6

3 Answers3

1

It's unclear to me if you want to handle the situation where you might have more than just a duplicate (i.e. three or more of the same Number2). I'll add another DataClass so you can see how to handle more than 2.

Also, it's unclear if you want the output to be a (1) Dictionary<int, Dictionary<int, int>> or a (2) Dictionary<int, List<DataClass>>. I'll provide you with both.

List<DataClass> list = new List<DataClass>()
{
    new DataClass { Number1 = 1, Number2 = 100 },
    new DataClass { Number1 = 2, Number2 = 100 },
    new DataClass { Number1 = 3, Number2 = 101 },
    new DataClass { Number1 = 4, Number2 = 102 },
    new DataClass { Number1 = 5, Number2 = 103 },
    new DataClass { Number1 = 6, Number2 = 104 },
    new DataClass { Number1 = 7, Number2 = 104 },
    new DataClass { Number1 = 8, Number2 = 104 },
};

(1)

Dictionary<int, Dictionary<int, int>> result =
    list
        .ToLookup(x => x.Number2)
        .SelectMany(xs => xs.Select((x, i) => new { x.Number1, x.Number2, i }))
        .GroupBy(x => x.i)
        .ToDictionary(
            gxs => gxs.Key + 1,
            gxs => gxs.ToDictionary(x => x.Number1, x => x.Number2));

(2)

Dictionary<int, List<DataClass>> result =
    list
        .ToLookup(x => x.Number2)
        .SelectMany(xs => xs.Select((v, i) => new { v, i }))
        .GroupBy(x => x.i, x => x.v)
        .ToDictionary(
            gxs => gxs.Key + 1,
            gxs => gxs.ToList());

The output I get from (2) is:

result 2

Enigmativity
  • 113,464
  • 11
  • 89
  • 172
0
List<DataClass> list = new List<DataClass>();
list.Add(new DataClass { Number1 = 1, Number2 = 100 });
list.Add(new DataClass { Number1 = 2, Number2 = 100 });
list.Add(new DataClass { Number1 = 3, Number2 = 101 });
list.Add(new DataClass { Number1 = 4, Number2 = 102 });
list.Add(new DataClass { Number1 = 5, Number2 = 103 });
list.Add(new DataClass { Number1 = 6, Number2 = 104 });
list.Add(new DataClass { Number1 = 7, Number2 = 104 });

var unique = new Dictionary<int, DataClass>();
var repeated = new List<DataClass>();
var result = new Dictionary<int, IEnumerable<DataClass>>();

foreach (var obj in list)
    if (!unique.TryAdd(obj.Number2, obj))
        repeated.Add(obj);

result.Add(1, unique.Values);
result.Add(2, repeated);
0
        List<DataClass> list = new List<DataClass>();
        list.Add(new DataClass {Number1= 1, Number2 = 100});
        list.Add(new DataClass {Number1= 2, Number2 = 100});
        list.Add(new DataClass {Number1= 3, Number2 = 101});
        list.Add(new DataClass {Number1= 4, Number2 = 102});
        list.Add(new DataClass {Number1= 5, Number2 = 103});
        list.Add(new DataClass {Number1= 6, Number2 = 104});
        list.Add(new DataClass {Number1= 7, Number2 = 104}); 
        var outPut = SplittedOutPut(list); 

private static Dictionary<int,IList<DataClass>> SplittedOutPut(IList<DataClass> fullList)
 {
      List<DataClass> Number1 = new List<DataClass>();
      List<DataClass> Number2 = new List<DataClass>();
      foreach (DataClass item in fullList)
      {
        if(!Number1.Exists( _ => _.Number2 == item.Number2))
            Number1.Add(item);
        else
            Number2.Add(item); 
      }

    var output = new Dictionary<int, IList<DataClass>>();
    outPut.Add(1,Number1);
    outPut.Add(2,Number2);
    return output;
  }

Side Note: One might think of using C# GroupBy Linq clause for this, but I just want to point out that LINQ group-by is not the same thing as a SQL group-by. A SQL group-by only produces the grouping keys as the result. A LINQ group-by is a hierarchical query that returns a sequence of groups, where each group contains the key and all the elements (rows) that made up the group. Thus it will be a much more expensive query than just traversing a list, which I have portrayed above.

yido
  • 307
  • 4
  • 16