#c_sharp #linq
Есть метод, возвращающий последовательность, состоящую из пар соседних элементов. Например, по последовательности {1,2,3} метод должен вернуть две пары: (1,2) и (2,3). Решение, которое сразу пришло в голову: return items .Take(items.Count() - 1) .Zip(items.Skip(1), Tuple.Create); Но в данном случае IEnumerable перечисляется больше одного раза. Как можно решить задачу без нескольких перечислений (сохранив метод ленивым)?
Ответы
Ответ 1
Например, так. Объявим метод расширения, который выдаёт последовательные пары: public static class EnumerableExtensions { public static IEnumerablePairwise ( this IEnumerable sequence, Func selector) { using (var it = sequence.GetEnumerator()) { if (!it.MoveNext()) yield break; T prev = it.Current; while (it.MoveNext()) yield return selector(prev, prev = it.Current); } } } И пользуемся: return items.Pairwise(Tuple.Create); Ответ 2
Как насчет отдельной функции? public IEnumerable> GetItems (IEnumerable source) { var prev = default(T); var firstVisited = false; foreach(var item in source) { if (firstVisited) { yield return Tuple.Create(prev, item); } else { firstVisited = true; } prev = item; } }
Комментариев нет:
Отправить комментарий