Вы можете сделать это точно все элементы между любыми двумя другими элементами:
var strings = new[] { "foo", "str1", "str2", ... "bar", ... "baz" };
var between = strings.SkipWhile(s => s != "foo").Skip(1)
.TakeWhile(s => s != "bar"); // "str1", "str2", ...
Если вы хотите, чтобы получить все, что между «Foo» и «Баз», кроме «бар», используйте этот (предполагается, что порядок «Foo», «бар», «Баз»):
var strings = new[] { "foo", "str1", "str2", ... "bar", ... "baz" };
var between = strings.SkipWhile(s => s != "foo").Skip(1)
.TakeWhile(s => s != "baz")
.Where(s => s != "bar"); // "str1", "str2", ...
Или, если ваш удобно с помощью Linq запросов с побочными эффектами, вы можете сделать это, чтобы разбить список ввода с определенным «стоп» слова:
var stops = new[] { "foo", "bar", "baz" };
var strings = new[] { "foo", "str1", "str2", "bar", "str3", "baz" };
var p = -1;
var partitions =
from s in strings
let i = Array.IndexOf(stops, s)
group s by p = i == -1 ? p : i into g
where g.Key == 0 || g.Key == 1
select g.Skip(1); // { "str1", "str2" }, { "str3" }
Или немного более эффективным (так как она прекращает обработку после третьего слова остановки):
var partitions =
(from s in strings
let i = Array.IndexOf(stops, s)
group s by p = i == -1 ? p : i)
.SkipWhile(g => g.Key < 0)
.Take(2)
.Select(g => g.Skip(1)); // { "str1", "str2" }, { "str3" }
Теперь этот метод немного грубо вокруг краев, и это несколько неудобным, когда речь идет о пункты перед «foo» или после «baz», но если вы только ищите предметы между «foo» и «baz», он должен работать на вас. Он имеет дополнительное преимущество, что порядок слов остановки не влияет на результаты.
Я бы сказал, да :) Вы уже что-то пробовали? Если да, поделитесь им с нами. – wonko79
Ну, я потратил два дня на поиски в Интернете и пытался использовать разные методы, но не нашел метода, который делает это, не просматривая дважды список. – dikyyn
См. Мой ответ для повторения только один раз. Выглядит не так хорошо, как другие решения, но и делает трюк. – wonko79