Имеем обобщённую (IEnumerable<T>) последовательность, например:
1, 1, 1, 2, 3, 3, 3
Требуется убедиться, что есть 1 как минимум один раз, 2 только один раз, и 3 как минимум один раз, после этого ничего быть не должно.
Это не валидно:
1, 1, 3
1, 2, 2, 3
1, 2, 3, 4
На данный момент самый простой рукопашный код будет примерно таким, для простоты выбран IEnumerable<int>.
Хотелось бы это реализовать встроенными средствами LINQ, но засада в том, что TakeWhile не даёт продолжение последовательности, а SkipWhile не даёт информацию сколько было пропущено, а CountWhile вообще такого нет.
Подскажите идеи
static void Test(IEnumerable<int> seq)
{
using var enumerator = seq.GetEnumerator();
// 1+
bool hasNext1 = false;
bool has1 = false;
while (enumerator.MoveNext())
{
if (enumerator.Current != 1) // predicate1
{
hasNext1 = true;
break;
}
has1 = true;
}
if (!has1)
{
Console.WriteLine("No 1");
return;
}
if (!hasNext1)
{
Console.WriteLine("No elements");
return;
}
// 2
bool hasNext2 = false;
bool has2 = false;
do
{
if (enumerator.Current != 2) // predicate2
{
hasNext2 = true;
break;
}
if (has2)
{
Console.WriteLine("2 is more than once !");
return;
}
has2 = true;
} while (enumerator.MoveNext());
if (!has2)
{
Console.WriteLine("No 2");
return;
}
if (!hasNext2)
{
Console.WriteLine("No elements");
return;
}
// 3+
bool hasNext3 = false;
bool has3 = false;
do
{
if (enumerator.Current != 3) // predicate3
{
hasNext3 = true;
break;
}
has3 = true;
} while (enumerator.MoveNext());
if (!has3)
{
Console.WriteLine("No 3");
return;
}
if (hasNext3)
{
Console.WriteLine("Too many elements");
return;
}
Console.WriteLine("OK");
}