如何使用Linq在列表中查找两个连续项目的子列表 [英] How to find a sub-list of two consecutive items in a list using Linq
问题描述
假设我们有一个像这样的字符串列表
Suppose that we have a list of strings like
"A", "B", "C", "D", "E", "F"
现在,我想在此列表中搜索包含两个连续项 D E
的子列表.如何使用Linq做到这一点?
Now I'd like to search for a sub-list of two consecutive items D E
in this list. How can I do this using Linq?
我的方法是:
int i = list.FindIndex(x => x == "D");
int j = list.FindIndex(x => x == "E");
int p = i < 0 || j < 0 ? -1 : (j == i + 1 ? i : -1);
这是正确的解决方案吗?有没有更短的解决方案?
Is it a correct solution? Is there any shorter solution?
推荐答案
您可以按照以下方式重写方法:
You could rewrite your approach as follows:
bool hasSublist = list
.SkipWhile(x => x != "D")
.Take(2)
.SequenceEquals(new[] {"D", "E"});
如果您需要 {"D","E"}
的起始索引,则可以添加一个将字母及其索引配对的选择.
If you need the starting index of {"D", "E"}
, you could add a select that pairs up letters and their indexes.
但是,您的方法存在的问题是,如果存在另一个"D"
而不是"E"
,例如
However, the problem with your approach is that it would miss the subsequence if there's another "D"
not followed by an "E"
, for example
"D" "A" "D" "B" "D" "C" "D" "D" "D" "E"
最后有一个"D""E"
,但是找到第一个"D"
后,您的方法就停止了.
There is a "D" "E"
at the end, but your approach stops after finding the first "D"
.
如果要查找长度为2的子列表,可以使用 Zip
,如下所示:
If you are looking for sublists of length 2, you could use Zip
, like this:
bool hasSublist = list
.Zip(list.Skip(1), (a, b) => new {a, b})
.Any(p => p.a == "D" && p.b == "E");
但是,这不适用于较长的子列表.
However, this does not scale for longer sub-lists.
使用普通的 for
循环会更好:
Using a plain for
loop would work much better:
for (var i = 0 ; i < list.Count-1 ; i++) {
if (list[i] == "D" && list[i+1] == "E") {
...
}
}
内部的 if
可以替换为 SequenceEquals
,以容纳任意长度的子列表:
The if
inside could be replaced with SequenceEquals
, accommodating sub-lists of any length:
var desiredSublist = new[] {"D", "E", "F"};
for (var i = 0 ; i < list.Count-desiredSublist+1 ; i++) {
if (list.Skip(i).SequenceEquals(desiredSublist)) {
...
}
}
这篇关于如何使用Linq在列表中查找两个连续项目的子列表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!