Используя 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 };

Существует ли простой способ в Linq, чтобы сделать что-то вроде "Выбора элементы от-1 до следующего отрицательного числа (или выхлоп списка)"? Успешный результат для-1 был бы (-1, 9, 8, 7, 6, 5, 4). Используя-2 дал бы результат (-2, 6, 15, 32).

Не проблема домашней работы. Я просто смотрю на реализацию с помощью a bool, a for цикл, и if удивление, если существует более чистый способ сделать это.

9
задан Clinton Pierce 8 March 2010 в 18:53
поделиться

4 ответа

Взгляните на метод расширения 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 не больше или равно нулю, вы получите пустой результат.

11
ответ дан 4 December 2019 в 13:01
поделиться

Обязательно ли это должен быть 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();
}
0
ответ дан 4 December 2019 в 13:01
поделиться
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);
0
ответ дан 4 December 2019 в 13:01
поделиться

Обновлено

На этот раз я протестировал код... Используя форму с двумя параметрами TakeWhile, мы можем заставить его принять первый элемент (j == 0) даже если тест для i не выполнен.

иа. SkipWhile(i => i != -1). TakeWhile((i, j) => i >= 0 || j == 0)

TakeWhile(Func) требует функции/лямбды, которая принимает два параметра. Первый — значение, которое необходимо проверить, а второй — индекс элемента.

5
ответ дан 4 December 2019 в 13:01
поделиться
Другие вопросы по тегам:

Похожие вопросы: