在Linq中将数百万个近似相似的字符串组合在一起?

Leg*_*end 0 c# string

我是Linq的新手,我正在尝试将我的一个SQL查询转换为C#来实现这一目标.我们假设我有以下字符串:

ABC-pqr-cv3-xa
LKJ-eqq-cb2-ya
POI-qqq-aaa-1
ABC-pqr-cv3-xb
UIO-qqq-xa
LKJ-eqq-cb2-za
POI-qqq-aaa-2
UIO-qqq-xb
LKJ-eqq-cb2-yb
POI-qqq-aaa-3
Run Code Online (Sandbox Code Playgroud)

我想根据整个字符串是否与最后一个字符匹配来对这些字符串进行分组.因此,以下是我期望的输出:

ABC-pqr-cv3-xa -- 1
ABC-pqr-cv3-xb -- 1

LKJ-eqq-cb2-ya -- 2
LKJ-eqq-cb2-yb -- 2

UIO-qqq-xa -- 3
UIO-qqq-xb -- 3

POI-qqq-aaa-1 -- 4
POI-qqq-aaa-2 -- 4
POI-qqq-aaa-3 -- 4

LKJ-eqq-cb2-za -- 5
Run Code Online (Sandbox Code Playgroud)

天真地做这件事需要进行O(n ^ 2)比较.有没有更好的方法来实现这一目标?群组编号本身并不重要.我正在尝试这个,如果我找到一个有效的方法,我会发一个答案.

spe*_*der 5

myLotsOfStrings.GroupBy(item => item.Substring(-1))
Run Code Online (Sandbox Code Playgroud)

这将产生一个IEnumerable<IGrouping<string,string>>,其中IGrouping<string,string>IEnumerable<string>该组中的项目.

它是使用一个构建的ILookup,在创建时,只迭代源一次并构建一个类似字典的结构,允许每个键有多个值.它可能会尽可能高效......更像是O(N).

鉴于您在下面的评论中列出的约束,您可能需要一个正则表达式来修剪您的组密钥.

正则表达式:

(^.*-(?=\d+$))|(^.*-[^-]*(?=[^-]$))
Run Code Online (Sandbox Code Playgroud)

将匹配POI-qqq-aaa-POI-qqq-aaa-123POI-qqq-aaa-xvPOI-qqq-aaa-xva.

所以把它们放在一起......

var regex = new Regex(@"(^.*-(?=\d+$))|(^.*-[^-]*(?=[^-]$))");
myLotsOfStrings
    //for each item, create anonymous object with 2 props, the original item
    //and the Match that is returned by running the regex over the item
    .Select(item => new{item, match = regex.Match(item)})
    //for each anonymous object (with properties item and match)
    //filter out any items where the regex failed to match 
    //(e.g match.Success is not true)
    .Where(x => x.match.Success)
    //now create an IEnumerable<IGrouping<string,string>>
    //where the value of the (successful) match is used for the key (match.value)
    //and the item in the group is the item property of the anonymous
    //object created above
    .GroupBy(x => x.match.Value, x => x.item)
Run Code Online (Sandbox Code Playgroud)

似乎可以做到这一点.