Leo Messi
Leo Messi

Reputation: 6166

List of objects with a list as a property of the object

Declaring a list of objects:

List<object> result = new List<object>();

and a list of int to store the ids:

List<int> ids = new List<int>();

I want to store in result objects containing the pair (string, list of int).

It works fine for the pair (string, int) but I want that when there are 2 identical strings to have only one object and the int values to be stored in a list.

ex: {pars = "xxx", id = 1} , {pars = "xxx", id = 2} becomes {pars = "xxx", id = (1,2 )}

For doing the initial functionality, I use a foreach through an object from which I take the string(pars) and the id:

    foreach (dataBinding in myData)
    {
        var x = string.Join(" ", dataBinding.Params.Select(p => p.myDescription));

        result.Add(new { pars = x, id = dataBinding.Id });

    }

there could be more strings in Params, that's why I use the join.

As it is here it works by creating objects having the form (string, int). But my aim is to make it (string, list of int) and if there are two objects with same string to combine them as I wrote before.

I tried to add ids list as the second property of the object but probably I'm not doing it correctly.

 result.Add(new { pars = x, ids = dataBinding.Id });

Upvotes: 0

Views: 1003

Answers (3)

Tim Schmelter
Tim Schmelter

Reputation: 460118

You can use LINQ, especially GroupBy:

Dictionary<string, List<int>> descriptionIDs = myData
    .GroupBy(x => x.myDescription)
    .ToDictionary(g => g.Key, g => g.Select(x => x.Id).ToList());

Now you have even a dictionary, not just a strange List<object> that contains anonymous types.

As someone mentioned, you can also use ToLookup which i'd also prefer:

var descriptionLookup = myData.ToLookup(x => x.myDescription);

Now you can get the ID-List easily:

var result = descriptionLookup.Select(g => new { pars = g.Key, ids = g.Select(x=> x.Id).ToList() }).ToList():

Upvotes: 1

user1672994
user1672994

Reputation: 10849

Below program depicts the current generic collection type, also allow to add a new value if Key Already exists.

using System;
using System.Collections.Generic;
                    
public class Program
{
    public static void Main()
    {
        
        MyProgram p = new MyProgram();
        
        p.Add("First" , 5);
        p.Add("Second" , 8);
        p.Add("Third" , 9);
        p.Add("First" , 6);
        p.Add("First" , 7);
        
        p.PrintDictionary();
    }
}


public class MyProgram
{
    private Dictionary<string, List<int>> dict = new Dictionary<string, List<int>>();
    
    public void Add(string key, int value)
    {
        if (dict.ContainsKey(key))
        {
            dict[key].Add(value);
        }
        else
        {
            dict.Add(key, new List<int>() {value});
        }
    }
    
    public void PrintDictionary()
    {
        foreach(var keyValue in dict)
        {
            Console.WriteLine("Key : " + keyValue.Key);
            
            foreach(var val in keyValue.Value)
            {
                Console.WriteLine(string.Format("\t Value : {0}", val));
            }
        }
    }
}

Output :

Key : First

Value : 5

Value : 6

Value : 7

Key : Second

Value : 8

Key : Third

Value : 9

Check this Live Fiddle.

Upvotes: 1

MarxWright
MarxWright

Reputation: 317

Perhaps I am not understanding the scenario fully but I suspect using the following would server your purpose.

List<Dictionary<string, List<int>>>

When the key doesn't exist you add it and when it does you just add to the List.

Upvotes: 1

Related Questions