Using LINQ to group a list of strings based on known substrings that they will contain
I have a known list of strings like the following:
List<string> groupNames = new List<string>(){"Group1","Group2","Group3"};
I also have a list of strings that is not known in advance that will be something like this:
List<string> dataList = new List<string>()
{
"Group1.SomeOtherText",
"Group1.SomeOtherText2",
"Group3.MoreText",
"Group2.EvenMoreText"
};
I want to do a LINQ statement that will take the dataList and convert it into either an anonymous object or a dictionary that has a Key of the group name and a Value that contains a list of the strings in that group. With the intention of looping over the groups and inner looping over the group list and doing different actions on the strings based on which group it is in.
I would like a data structure that looks something like this:
var grouped = new
{
new
{
Key="Group1",
DataList=new List<string>()
{
"Group1.SomeOtherText",
"Group1.SomeOtherText2"
}
},
new
开发者_运维技巧 {
Key="Group2",
DataList=new List<string>()
{
"Group2.EvenMoreText"
}
}
...
};
I know I can just loop through the dataList and then check if each string contains the group name then add them to individual lists, but I am trying to learn the LINQ way of doing such a task.
Thanks in advance.
EDIT:
Just had another idea... What if my group names were in an Enum?
public enum Groups
{
Group1,
Group2,
Group3
}
How would I get that into a Dictionary>?
This is what I am trying but i am not sure how to form the ToDictionary part
Dictionary<Groups,List<string>> groupedDictionary = (from groupName in Enum.GetNames(typeof(Groups))
from data in dataList
where data.Contains(groupName)
group data by groupName).ToDictionary<Groups,List<string>>(...NOT SURE WHAT TO PUT HERE....);
EDIT 2:
Found the solution to the Enum question:
var enumType = typeof(Groups);
Dictionary<Groups,List<string>> query = (from groupName in Enum.GetValues(enumType).Cast<Groups>()
from data in dataList
where data.Contains(Enum.GetName(enumType, groupName))
group data by groupName).ToDictionary(x => x.Key, x=> x.ToList());
That looks like:
var query = from groupName in groupNames
from data in dataList
where data.StartsWith(groupName)
group data by groupName;
Note that this isn't a join, as potentially there are overlapping group names "G" and "Gr" for example, so an item could match multiple group names. If you could extract a group name from each item (e.g. by taking everything before the first dot) then you could use "join ... into" to get a group join. Anyway...
Then:
foreach (var result in query)
{
Console.WriteLine("Key: {0}", result.Key);
foreach (var item in result)
{
Console.WriteLine(" " + item);
}
}
If you really need the anonymous type, you can do...
var query = from groupName in groupNames
from data in dataList
where data.StartsWith(groupName)
group data by groupName into g
select new { g.Key, DataList = g.ToList() };
精彩评论