How to find a sub-list of two consecutive items in a list using Linq

前端 未结 5 1706
长发绾君心
长发绾君心 2021-01-26 19:56

Suppose that we have a list of strings like

\"A\", \"B\", \"C\", \"D\", \"E\", \"F\"

Now I\'d like to search for a sub-list of

5条回答
  •  不要未来只要你来
    2021-01-26 20:49

    You could rewrite your approach as follows:

    bool hasSublist = list
        .SkipWhile(x => x != "D")
        .Take(2)
        .SequenceEquals(new[] {"D", "E"});
    

    If you need the starting index of {"D", "E"}, you could add a select that pairs up letters and their indexes.

    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"
    

    There is a "D" "E" at the end, but your approach stops after finding the first "D".

    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.

    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") {
            ...
        }
    }
    

    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)) {
            ...
        }
    }
    

提交回复
热议问题