# Creating a dictionary of strings and list of strings

I have a List of objects, List<myObject> objectList, and each object contains a List of strings like so:

myObject: StringList( "A_1", "B_1", "C_1", "D_1", "E_1", "F_1" )
myObject: StringList( "A_2", "B_2", "C_1", "D_2", "E_2", "F_1" )
myObject: StringList( "A_2", "B_3", "C_1", "D_3", "E_2", "F_1" )


I'm trying to merge the lists into a dictionary of: Dictionary<string, List<string>>, where the final results will look like so:

Dictionary: { [A:1,2]  [B:1,2,3]  [C:1]  [D:1,2,3]  [E:1,2]  [F:1] }


Here is what I have done, and it does work:

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

foreach (myObject result in objectList)
{
foreach (var item in result.StringList)
{
string Key = item.Split('_')[0];
string Value = item.Split('_')[1];

List<string> sValue = new List<string>();
bool exists = dict.TryGetValue(Key, out sValue);

if (exists && !sValue.Contains(Value))
{
dict[Key] = sValue;
}
else if (!exists)
{
sValue = sValue ?? new List<string>();
}
}
}


Is there a better way to do this, where I don't have to use two foreach loops? Is there a way to do it without using any foreach loops?

I have tried using lambda but this is as far as I got:

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

foreach (myObject result in objectList)
{
dict = result.StringList.Select(x => x.Split('_'))
.GroupBy(x => x[0])
.ToDictionary(x => x.Key, x => x.Select(g => g[1]).ToList());
}


The problem is that the expression keeps overwriting any existing entries in the dictionary each time I iterate through the loop.

Is there a way to keep the existing entries, groupby the Key and add to the existing list of values but don't duplicate any values?

I think the answer lies in this part of the expression:

x => x.Select(g => g[1]).ToList()


but I'm not 100% sure.

## migrated from stackoverflow.comNov 27 '13 at 16:33

This question came from our site for professional and enthusiast programmers.

• Did you try SelectMany? – Mike Cheel Nov 27 '13 at 16:28

Just get rid of the outer foreach as well:

dict = objectList.SelectMany(x => x.StringList)
.Select(x => x.Split('_'))
.GroupBy(x => x[0])
.ToDictionary(x => x.Key, x => x.Select(g => g[1]).Distinct().ToList());


SelectMany retrieves all the StringLists and flattens them into one single list:

"A_1", "B_1", ..., "F_1", "A_2", "B_2", ...

• I think you want a distinct in there as well so that A is 1,2 rather than 1,2,2. – Chris Nov 27 '13 at 16:39
• x => x.Select(g => g[1]).Distinct().ToList() – Ahmed KRAIEM Nov 27 '13 at 16:40
• Note that Distinct destroys order, so it might be 1,2 or 2,1. – Tim S. Nov 27 '13 at 16:48
• @Heinzi - Thanks so much! This works perfectly! Much simpler and more elegant. For the life of me, I couldn't figure this out...a million times thank you! – user3042376 Nov 27 '13 at 16:59
• @Groo Like a comment at my link says, "what you say could be true [that it preserves first-found order], but it would be a bad idea to rely on that behavior" (because it is documented as being an unordered sequence, you should treat it as such). Also, I don't know that objectList had it sorted to begin with, the example just happens to have it so (I think). – Tim S. Nov 27 '13 at 17:07