Учитывая список элементов как так:
int[] ia = new int[] { -4, 10, 11, 12, 13, -1, 9, 8, 7, 6, 5, 4, -2,
6, 15, 32, -5, 6, 19, 22 };
Существует ли простой способ в Linq, чтобы сделать что-то вроде "Выбора элементы от-1 до следующего отрицательного числа (или выхлоп списка)"? Успешный результат для-1 был бы (-1, 9, 8, 7, 6, 5, 4). Используя-2 дал бы результат (-2, 6, 15, 32).
Не проблема домашней работы. Я просто смотрю на реализацию с помощью a bool
, a for
цикл, и if
удивление, если существует более чистый способ сделать это.
Взгляните на метод расширения Linq TakeWhile . Выбирает элементы из списка до тех пор, пока условие истинно, остальные пропускает.
Пример:
int[] ia = new int[] { -4, 10, 11, 12, 13, -1, 9, 8, 7, 6, 5, 4, -2,
6, 15, 32, -5, 6, 19, 22 };
var result = ia
.SkipWhile(i => i != -1)
.Skip(1)
.TakeWhile(i => i >= 0);
Обратите внимание на пропуск (1) после SkipWhile. SkipWhile пропускает все до, но не включает соответствующий элемент. TakeWhile затем принимает элементы, вплоть до совпадающего элемента, но не включая его. Поскольку -1 не больше или равно нулю, вы получите пустой результат.
Обязательно ли это должен быть Linq? Вы можете использовать методы расширений, чтобы получить более чистое решение.
int[] ia = new int[] { -4, 10, 11, 12, 13, -1, 9, 8, 7, 6, 5, 4, -2,
6, 15, 32, -5, 6, 19, 22 };
// Call the Extension method
int[] results = ia.SelectRangeLoop(-2);
// Print Results
for (int i = 0; i < results.Length; i++)
{
Console.Write(" {0} ", results[i]);
}
Метод для SelectRangeLoop приведен ниже.
public static int[] SelectRangeLoop(this int[] value, int startNumber)
{
List<int> results = new List<int>();
bool inNegative = false;
for (int i = 0; i < value.Length; i++)
{
if (value[i] == startNumber)
{
inNegative = true;
results.Add(value[i]);
continue;
}
if (inNegative && value[i] < 0)
{
break;
}
if (inNegative)
{
results.Add(value[i]);
}
}
return results.ToArray();
}
var first = ia.Select((i, index) => new {i, index}).Where((i, index) => i.i == x).First();
var ind = first.index;
var second = ia.SkipWhile( (i, index) => index <= ind).TakeWhile(i => i > 0);
var ints = new[]{first.i}.Union(second);
Обновлено
На этот раз я протестировал код... Используя форму с двумя параметрами TakeWhile, мы можем заставить его принять первый элемент (j == 0)
даже если тест для i
не выполнен.
иа. SkipWhile(i => i != -1). TakeWhile((i, j) => i >= 0 || j == 0)
TakeWhile(Func
требует функции/лямбды, которая принимает два параметра. Первый — значение, которое необходимо проверить, а второй — индекс элемента.