开发者

Using LINQ to group a list of strings based on known substrings that they will contain

开发者 https://www.devze.com 2023-03-23 19:22 出处:网络
I have a known list of strings like the following: List<string> groupNames = new List<string>(){\"Group1\",\"Group2\",\"Group3\"};

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() };
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号