Amitd
Amitd

Reputation: 4849

Create a nested list from a flat list using Linq

I have a list of strings like

A01,B01 ,A02, B12, C15, A12,  ... 

I want to unflatten the list into List of lists or dicitionary of lists such that
all strings starting with the same letter are group together (using linq)

A -> A01 , A02 , Al2
B -> B01 , B12
C -> C15

or

    A -> 01 , 02 , l2
    B -> 01 , 12
    C -> 15

For now I just iterate the list using for loop and add the values to the approp list from dictionary.

(may not be right!)

   Dictionary<string, List<string>> dict = new Dictionary<string, List<string>>();

         foreach( string str in stringList)
         {
            string key = str.Substring(0,1);
            if (!dict.ContainsKey(key)){
                dict[key] = new List<string>();
            }

            dict[key].Add(str);
         }

Edit :
Oh sorry i forgot to add this , I have a list of Category objs , and these are Category names.
I need to retrieve something like Dictionary<string, List<Category>> , going forward i want to bind this to a nested list . (asp.net/ mvc )

Is there a better way to do the same using Linq?

Upvotes: 2

Views: 2170

Answers (3)

Stuart Blackler
Stuart Blackler

Reputation: 3772

Coming from the chat room, try this. I know it's not the most elegant solution, there is probably better.

List<string> listOfStrings = {"A01", "B01", "A02", "B12", "C15", "A12"}.ToList();


var res = listOfStrings.Select(p => p.Substring(0, 1)).Distinct().ToList().Select(p => 
new {
       Key = p,
       Values = listOfStrings.Where(c => c.Substring(0, 1) == p)
}).ToList();

foreach (object el_loopVariable in res) {
     el = el_loopVariable;
     foreach (object x_loopVariable in el.Values) {
         x = x_loopVariable;
         Console.WriteLine("Key: " + el.Key + " ; Value: " + x);
     }
}

Console.Read();

Gives the following output:

enter image description here

Upvotes: 1

ashcliffe
ashcliffe

Reputation: 138

If you want to use dictionary, you may want this

       List<String> strList = new List<String>();
        strList.Add("Axxxx");
        strList.Add("Byyyy");
        strList.Add("Czzzz");
        Dictionary<String, String> dicList = strList.ToDictionary(x => x.Substring(0, 1));
        Console.WriteLine(dicList["A"]);

Upvotes: 0

Jon Skeet
Jon Skeet

Reputation: 1502036

It sounds like you want a Lookup, via the ToLookup extension method:

var lookup = stringList.ToLookup(x => x.Substring(0, 1));

A lookup will let you do pretty much anything you could do with the dictionary, but it's immutable after construction. Oh, and if you ask for a missing key it will give you an empty sequence instead of an error, which can be very helpful.

Upvotes: 5

Related Questions