首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >我怎么能从Linq的TakeWhile中多拿一条呢?

我怎么能从Linq的TakeWhile中多拿一条呢?
EN

Stack Overflow用户
提问于 2010-02-11 04:42:53
回答 5查看 10.6K关注 0票数 20

(感兴趣的代码行是最后一个代码,其余代码仅用于完整的表示)

使用下面的代码,我想让选民投票,直到我的超过了所需的最大票数,但是在达到最大票数之前它就停止了,所以我的选民池比我想要的少一个选民。

在LINQ是否有一条干净的道路,在那里我可以让它投票,直到它达到最大票数?我知道我可以再添加一个投票者,或者在一个循环中这样做,但我很好奇是否有一个好的方法来替代LINQ。

代码语言:javascript
复制
var voters = new List<Person>
                             {
                                 new Person("Alice", Vote.Yes ),
                                 new Person("Bob", Vote.Yes),
                                 new Person("Catherine", Vote.No),
                                 new Person("Denzel", Vote.Yes),
                                 new Person("Einrich", Vote.Abstain),
                                 new Person("Frederica", Vote.Abstain),
                                 new Person("Goeffried", Vote.Abstain),
                             };
            voters.Single(c => c.Name == "Alice").Voices = 100;
            voters.Single(c => c.Name == "Bob").Voices = 150;
            voters.Single(c => c.Name == "Catherine").Voices = 99;
            voters.Single(c => c.Name == "Denzel").Voices = 24;
            voters.Single(c => c.Name == "Einrich").Voices = 52;
            voters.Single(c => c.Name == "Frederica").Voices = 39;
            voters.Single(c => c.Name == "Goeffried").Voices = 99;

// this takes voters until we are BEFORE reaching X voices...
int voicesSoFar = 0;
int voicesNeeded = 300;
var eligibleVoters = voters.TakeWhile((p => (voicesSoFar += p.Voices) < voicesNeeded ));
EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2010-02-11 05:24:27

你在找

代码语言:javascript
复制
voters.TakeWhile(p => {
   bool exceeded = voicesSoFar > voicesNeeded ;
   voicesSoFar += p.Voices;
   return !exceeded;
});

如果您坚持使用一条直线,这将通过比较前面的值来实现:

代码语言:javascript
复制
voters.TakeWhile(p => (voicesSoFar += p.Voices) - p.Voices < voicesNeeded);
票数 18
EN

Stack Overflow用户

发布于 2011-07-25 14:19:19

在我想要执行一个函数并将其包含到一个结束条件的情况下,我执行了:

代码语言:javascript
复制
public static IEnumerable<T> TakeUntilIncluding<T>(this IEnumerable<T> list, Func<T, bool> predicate)
{
    foreach(T el in list)
    {
        yield return el;
        if (predicate(el))
            yield break;
    }
}

为我工作!我认为这是一个与实现无关的解决方案,就像Jason的解决方案,但更简单。

票数 25
EN

Stack Overflow用户

发布于 2010-02-11 05:07:01

只需编写自己的扩展方法:

代码语言:javascript
复制
static class IEnumerableExtensions {
    public static IEnumerable<T> TakeUntil<T>(
        this IEnumerable<T> elements,
        Func<T, bool> predicate
    ) {
        return elements.Select((x, i) => new { Item = x, Index = i })
                       .TakeUntil((x, i) => predicate(x.Item))
                       .Select(x => x.Item);
    }

    public static IEnumerable<T> TakeUntil<T>(
        this IEnumerable<T> elements,
        Func<T, int, bool> predicate
    ) {
        int i = 0;
        foreach (T element in elements) {
            if (predicate(element, i)) {
                yield return element;
                yield break;
            }
            yield return element;
            i++;
        }
    }
}

用法:

代码语言:javascript
复制
var eligibleVoters = voters.TakeUntil(
                         p => (voicesSoFar += p.Voices) >= voicesNeeded
                     );

foreach(var voter in eligibleVoters) {
    Console.WriteLine(voter.Name);
}

输出:

代码语言:javascript
复制
Alice
Bob
Catherine
票数 7
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/2242318

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档