'Smart' grouping with LINQ

前端 未结 2 822
囚心锁ツ
囚心锁ツ 2020-12-11 18:51

I have a list of strings and I want to convert it to some kind of grouped list, whereby the values would be grouped by their location in the list (not normal grouping, but i

2条回答
  •  挽巷
    挽巷 (楼主)
    2020-12-11 19:20

    The extension method from this answer does pretty much what you ask (Microsoft also provide an implementation to group contiguous items in a sequence):

    public static IEnumerable> 
        GroupConsecutive(this IEnumerable set, Func predicate)
    {
        var i = 0;
        var k = 0;
        var ranges = from e in set
                     let idx = ++i
                     let next = set.ElementAtOrDefault(idx)
                     let key = (predicate(e, next)) ? k : k++
                     group e by key into g
                     select g;
        return ranges;
    }
    

    You could use it as follows:

    void Main()
    {
        LinkedList myList = new LinkedList();
        myList.AddLast("aaa");
        myList.AddLast("aaa");
        myList.AddLast("bbb");
        myList.AddLast("bbb");
        myList.AddLast("aaa");
        myList.AddLast("aaa");
        myList.AddLast("aaa");
        IGrouping ggg;
    
        var groups=myList.GroupConsecutive((a,b)=>a==b);
    
        ILookup lookup=groups.ToLookup(g=>g.First(),g=>g.Count());
    
        foreach(var x in lookup["aaa"])
        {
            Console.WriteLine(x); //outputs 2 then 3
        }
        foreach(var x in lookup["bbb"])
        {
            Console.WriteLine(x); //outputs 2
        }
    
    }
    

    Notice that the final container is an ILookup which behaves a little like a Dictionary, but allows one to store multiple values against a single key.

提交回复
热议问题