在我的工作场所,我有一个简化的日志文件,其中有IM'ed(即时消息)谁。对于我们的简单示例,让我们假装日志是一个由2个制表符分隔的列组成的文本文件。如果人A是IM人B,反之亦然,它在日志中显示为AB或BA。即时通讯的方向并不重要,只是该对方已经相互接触。
我有一个包含2个研究组的列表,X和Y,其中包含A,B,C等人的名字。我的目标是找出X和Y组中的哪些人通过IM进行了IM看着日志文件。我无法根据人数或不同成员对X组和Y组的成员做出任何假设。
如果这是一个我想象使用连接的数据库,但我想学习如何用C#/ LINQ做到这一点。如何在日志文件中找到Group X和Group Y的交集?
我想我想联合lstGroupX和lstGroupY的成员,使其成员之间所有可能的1对1组合看起来像AB或BA,然后在日志文件中查找AB或BA。
//assume the log is in a list called lstLog
//a list called lstGroupX contains the names GroupX members
//a list called lstGroupY contains the names GroupY members
var IMBuddies = lstLog.Intersect(lstGroupX).Intersect(lstGroupY);
我不认为上述行是完全正确的。我真正想要的是这样的事情
var IMBuddies = lstLog.Intersect(all possible permutations where lstGroupX members contacts lstGroupY members and vice versa)
但我不知道该怎么做。
答案 0 :(得分:1)
这应该完成工作:
var IMBuddies = lstLog.FindAll(x =>
!string.IsNullOrEmpty(lstGroupX.Find(y => x.Contains(y))) &&
!string.IsNullOrEmpty(lstGroupY.Find(y => x.Contains(y)))
);
这可以分为3个部分,我们放在lstLog上的条件,我们放在lstGroupY上的条件,以及我们放在lstGroupX上的条件。 lamda表达式应该读取类似x =>的内容。条件x必须满足(即x => x.Id == 1会得到Id为1的元素。)
lstLog的条件:
lstLog.FindAll(x => !string.IsNullOrEmpty(<return element of lstGroupY condition>) && !string.IsNullOrEmpty(<return element of lstGroupX condition>))
简而言之,它要求所有不从lstGroupX条件返回null的元素,并且不从lstGroupY条件返回null
lstGroupX的条件:
lstGroupX.Find(y=> x.Contains(y))
这将获取lstGroupX中的每个元素,并检查lstLog条件的当前元素是否包含该元素。因此,如果x代表lstLog中的“AB”而y代表lstGroupX中的“B”,则检查“AB”是否包含“B”。如果是,则返回“B”。如果没有找到任何元素,那么它应该返回null(因此原因是!string.IsNullOrEmpty被添加到那里)。
lstGroupY的条件:
lstGroupY.Find(y=> x.Contains(y))
这与lstGroupX的条件相同,只是它正在查看lstGroupY中的元素。
将他们放在一起:
因此,将所有条件放在一起,它基本上查看lstLog中的每个元素,如果lstGroupX中的元素包含在lstLog元素中,并且如果lstGroupY中的元素包含在lstLog元素中,则会添加它返回集合。
应该注意FindAll方法返回IEnumerable,而Find方法一旦找到第一个就停止。