Требуется убедиться, что есть 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;
}
// 2bool 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");
}
Здравствуйте, Baiker, Вы писали:
B>Здравствуйте, _NN_, Вы писали:
_NN>>Требуется убедиться, что есть 1 как минимум один раз, 2 только один раз, и 3 как минимум один раз
B>ээ... а регэкспы разве не решат такую задачу?
Помогли бы если бы это была строка, но тут не строка.
Как раз построение автомата из реализации регэкспов могло бы помочь, но это внутренняя реализация.
У меня общий IEnumerable<T> и общие предикаты Func<T, bool>, числа даны для простоты.
Здравствуйте, _NN_, Вы писали:
_NN>Хотелось бы это реализовать встроенными средствами LINQ, но засада в том, что TakeWhile не даёт продолжение последовательности, а SkipWhile не даёт информацию сколько было пропущено, а CountWhile вообще такого нет.
Не совсем.
Тут дело в том, что часть последовательности мы обрабатываем энергично, а остальную часть лениво.
Методы расширения обычно обходят всю последовательность либо только энергично либо только лениво.
Здравствуйте, _NN_, Вы писали:
_NN>Это подходит если не нужны дополнительные действия над элементами.
Используйте Aggregate c resultSelector
_NN>А вот если нужна обработка для условия как у меня, то не подойдёт.
Какая у вас обработка? Я не вижу.
Re[4]: Подсчёт элементов с последующим проходом по последовательнос
Здравствуйте, gandjustas, Вы писали:
G>Здравствуйте, _NN_, Вы писали:
_NN>>Это подходит если не нужны дополнительные действия над элементами. G>Используйте Aggregate c resultSelector
_NN>>А вот если нужна обработка для условия как у меня, то не подойдёт. G>Какая у вас обработка? Я не вижу.
Код более менее такой:
record A(int X);
bool Is1(A a) => a.X == 1;
bool Is2(A a) => a.X == 2;
bool Is3(A a) => a.X == 3;
var xs = new A[] { new(1), new(1), new(1), new(2), new(3), new(3), new(3) };
// Нужна последовательность A.X в вышеуказанном порядке "1" несколько раз, "2" один раз, "3" несколько раз, конец.
Здравствуйте, _NN_, Вы писали:
_NN>Код более менее такой: _NN>
_NN>record A(int X);
_NN>bool Is1(A a) => a.X == 1;
_NN>bool Is2(A a) => a.X == 2;
_NN>bool Is3(A a) => a.X == 3;
_NN>var xs = new A[] { new(1), new(1), new(1), new(2), new(3), new(3), new(3) };
_NN>// Нужна последовательность A.X в вышеуказанном порядке "1" несколько раз, "2" один раз, "3" несколько раз, конец.
_NN>
using System;
using System.Linq;
var xs = new A[] {new(1), new(1), new(1), new(2), new(3), new(3), new(3)};
var x = xs.Aggregate(1, (s, a) => (s, a) switch {
(1,var m) when Is1(m) => 1,
(1,var m) when Is2(m) => 2,
(2,var m) when Is3(m) => 3,
(3,var m) when Is3(m) => 3,
_ => -1
});
Console.WriteLine(x);
bool Is1(A a) => a.x == 1;
bool Is2(A a) => a.x == 2;
bool Is3(A a) => a.x == 3;
record A(int x);
Re[6]: Подсчёт элементов с последующим проходом по последовательнос
Здравствуйте, Sharov, Вы писали:
S>Здравствуйте, _NN_, Вы писали:
_NN>>Имеем обобщённую (IEnumerable<T>) последовательность, например:
_NN>>
_NN>>1, 1, 1, 2, 3, 3, 3
_NN>>
_NN>>Требуется убедиться, что есть 1 как минимум один раз, 2 только один раз, и 3 как минимум один раз, после этого ничего быть не должно.
S>Пройтись циклом и перегнать в словарь, по ходу проверяя кол-во эл-ов. Типа если 2 уже есть, то ошибка.
Тогда нет проверки порядка и лишних элементов.
Тут в ветке подсказали достаточно лаконичное решение.