使用 Linq 过滤子集

发布于 2024-09-01 13:34:47 字数 261 浏览 11 评论 0原文

想象一下有一个很长的枚举,太大而无法合理地转换为列表。还想象我想从列表中删除重复项。最后想象一下,我知道只有初始枚举的一小部分可能包含重复项。最后一点使问题变得实际。

基本上我想根据某些谓词过滤出列表,并且只在该子集上调用 Distinct() ,但也与谓词返回 false 的枚举重新组合。

谁能想到一个好的惯用 Linq 方法来做到这一点?我想问题

可以归结为以下几点:使用 Linq 如何对谓词枚举执行选择性处理,并将结果流与谓词中被拒绝的案例重新组合?

Imagine a have a very long enunumeration, too big to reasonably convert to a list. Imagine also that I want to remove duplicates from the list. Lastly imagine that I know that only a small subset of the initial enumeration could possibly contain duplicates. The last point makes the problem practical.

Basically I want to filter out the list based on some predicate and only call Distinct() on that subset, but also recombine with the enumeration where the predicate returned false.

Can anyone think of a good idiomatic Linq way of doing this? I suppose the question boils down to the following:

With Linq how can you perform selective processing on a predicated enumeration and recombine the result stream with the rejected cases from the predicate?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

孤独难免 2024-09-08 13:34:47

您可以通过遍历列表两次来完成此操作,一次应用谓词和重复数据删除,第二次应用谓词的否定。另一个解决方案是编写您自己的 Where 扩展方法的变体,将不匹配的条目推送到侧面的缓冲区中:

IEnumerable<T> WhereTee(this IEnumerable<T> input, Predicate<T> pred, List<T> buffer)
{
    foreach (T t in input)
    {
        if (pred(t))
        {
            yield return t;
        }
        else
        {
            buffer.Add(t);
        }
    }
}

You can do it by traversing the list twice, once to apply the predicate and dedup, and a second time to apply the negation of the predicate. Another solution is to write your own variant of the Where extension method that pushes non-matching entries into a buffer on the side:

IEnumerable<T> WhereTee(this IEnumerable<T> input, Predicate<T> pred, List<T> buffer)
{
    foreach (T t in input)
    {
        if (pred(t))
        {
            yield return t;
        }
        else
        {
            buffer.Add(t);
        }
    }
}
独自←快乐 2024-09-08 13:34:47

您能否提供更多有关如何重新组合元素的详细信息。

我能想到解决这个问题的一种方法是使用 .Net 4.0 的 Zip 运算符,如下所示。

var initialList  = new List<int>();

    var resjectedElemnts = initialList.Where( x=> !aPredicate(x) );
    var accepetedElements = initialList.Where( x=> aPredicate(x) );

    var result = accepetedElements.Zip(resjectedElemnts,(accepted,rejected) => T new {accepted,rejected});

这将创建一对拒绝和接受元素的列表。但列表的大小将受到两个输入之间较短列表的限制。

Can you give a little more details on how you would like to recombine the elments.

One way i can think of solving this problem is by using the Zip operator of .Net 4.0 like this.

var initialList  = new List<int>();

    var resjectedElemnts = initialList.Where( x=> !aPredicate(x) );
    var accepetedElements = initialList.Where( x=> aPredicate(x) );

    var result = accepetedElements.Zip(resjectedElemnts,(accepted,rejected) => T new {accepted,rejected});

This will create a list of pair of rejected and accepeted elements. But the size of the list will be contrained by the shorter list between the two inputs.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文