How could I take 1 more item from Linq's TakeWhile?

后端 未结 5 2035
难免孤独
难免孤独 2021-01-01 16:45

(line of code of interest is the last one, the rest is just for a full representation)

Using the following code, I wanted to take VOTERS until I exceeded

5条回答
  •  北荒
    北荒 (楼主)
    2021-01-01 17:25

    Just write your own extension method:

    static class IEnumerableExtensions {
        public static IEnumerable TakeUntil(
            this IEnumerable elements,
            Func predicate
        ) {
            return elements.Select((x, i) => new { Item = x, Index = i })
                           .TakeUntil((x, i) => predicate(x.Item))
                           .Select(x => x.Item);
        }
    
        public static IEnumerable TakeUntil(
            this IEnumerable elements,
            Func predicate
        ) {
            int i = 0;
            foreach (T element in elements) {
                if (predicate(element, i)) {
                    yield return element;
                    yield break;
                }
                yield return element;
                i++;
            }
        }
    }
    

    Usage:

    var eligibleVoters = voters.TakeUntil(
                             p => (voicesSoFar += p.Voices) >= voicesNeeded
                         );
    
    foreach(var voter in eligibleVoters) {
        Console.WriteLine(voter.Name);
    }
    

    Output:

    Alice
    Bob
    Catherine
    

提交回复
热议问题