Читать пропущенные данные

1

У меня есть IEnumerable T. Я хочу пропустить определенное количество T, но в процессе я также хочу прочитать эти T. Вы можете прочитать Ts с помощью Take() и пропустить их с помощью Skip(), но что повлечет за собой множественные перечисления.

Мне нужно прочитать N элементов, обработать их, а затем вернуть все непрочитанные элементы в виде IEnumerable в одном перечислении.

Изменение: я пытаюсь передать IEnumerable методу, который принимает Stream-подобный. А именно, я должен реализовать только метод

public int Read(T[] readBuffer, int offset, int count)

Проблема в том, что мне нужно заранее перечислить прошедшие данные, чтобы сохранить позицию, а также прочитать данные, которые нужно передать обратно во входном буфере.

До сих пор я пробовал это:

    public static IEnumerable<T> SkipTake<T>(this IEnumerable<T> input, int num, Action<List<T>> take)
    {
        var enumerator = input.GetEnumerator();
        var chunk = new List<T>();
        for (int i = 0; i < num; ++num)
        {
            chunk.Add(enumerator.Current);
            if (!enumerator.MoveNext())
                break;
        }
        take(chunk);
        yield return enumerator.Current;
        while (enumerator.MoveNext())
            yield return enumerator.Current;
    }

Не много удачи.

  • 0
    вы не можете пропустить и взять при повторении только один раз, просто взять обе части
  • 0
    Я думаю, что вы должны сделать 2 перечисления из этого: один содержит все элементы, кроме первого N, другой содержит только первые N элементов. Затем, оф, вам придется перечислить оба
Показать ещё 6 комментариев
Теги:
linq
ienumerable

1 ответ

1
Лучший ответ

Похоже, что ваша реализация не вызывает MoveNext() в нужное время. Вы должны вызвать MoveNext() прежде чем вы сможете получить Current элемент:

public static IEnumerable<T> SkipTake<T>(this IEnumerable<T> input, int num, Action<List<T>> take)
{
    var enumerator = input.GetEnumerator();
    var chunk = new List<T>();
    for (int i = 0; i < num; ++num)
    {
        if (!enumerator.MoveNext())
            break;
        chunk.Add(enumerator.Current);
    }
    take(chunk);
    while (enumerator.MoveNext())
        yield return enumerator.Current;
}

EDIT: просто для того, чтобы это было ясно, вот пример использования:

var list = new List<string>() {"This", "is", "an", "example", "!"};
var res = list.SkipTake(2, chunk =>
{
    Console.WriteLine(chunk.Count());
});
Console.WriteLine(res.Count());

Выход

2 3

и коллекции содержат

{"Это"}

а также

{"пример", "!"}

соответственно, и первоначальный list коллекции не был изменен.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню