“智能”与LINQ分组 [英] 'Smart' grouping with LINQ

查看:127
本文介绍了“智能”与LINQ分组的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

予有字符串的列表,我想将其转换为某种分组的列表,由此,值将由它们的位置中的表(未正常分组进行分组,但在某种程度上,同一项目在一组只有当他们在一起)。请看下面的例子:

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 in a way, that the same items are in a group only if they are together). Consider the following example:

LinkedList<string> myList = new LinkedList<string>();
myList.AddLast("aaa");
myList.AddLast("aaa");
myList.AddLast("bbb");
myList.AddLast("bbb");
myList.AddLast("aaa");
myList.AddLast("aaa");
myList.AddLast("aaa");

LinkedList<MyTuple> groupedList = new LinkedList<MyTuple>();
groupedList.AddLast(new MyTuple("aaa", 2));
groupedList.AddLast(new MyTuple("bbb", 2));
groupedList.AddLast(new MyTuple("aaa", 3));

可以这样改造与LINQ做,或者我应该写算法通常的方式与循环?

Can this transformation be done with LINQ or should I write the algorithm usual way with loops?

推荐答案

从扩展方法<一href="http://stackoverflow.com/questions/1478070/how-to-group-consecutive-similar-items-of-a-collection/2528167#2528167">this回答没有pretty的你问太多什么(微软还提供实施序列中组相邻的项目):

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<IGrouping<int, T>> 
    GroupConsecutive<T>(this IEnumerable<T> set, Func<T, T, bool> 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<string> myList = new LinkedList<string>();
    myList.AddLast("aaa");
    myList.AddLast("aaa");
    myList.AddLast("bbb");
    myList.AddLast("bbb");
    myList.AddLast("aaa");
    myList.AddLast("aaa");
    myList.AddLast("aaa");
    IGrouping<int,string> ggg;

    var groups=myList.GroupConsecutive((a,b)=>a==b);

    ILookup<string,int> 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
    }

}

请注意,最后的容器是一个 ILookup 其行为有点像词典,但允许一个用于存储多个值针对单个键

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.

这篇关于“智能”与LINQ分组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆