是否有更简洁的 linq 方式来“联合”单个项目?

Posted

技术标签:

【中文标题】是否有更简洁的 linq 方式来“联合”单个项目?【英文标题】:Is there a neater linq way to 'Union' a single item? 【发布时间】:2011-04-01 17:21:45 【问题描述】:

如果我有两个序列并且我想一起处理它们,我可以合并它们然后我们就走了。

现在假设我想在两个序列之间处理一个项目。我可以通过创建一个包含单个项目的数组来获取它,但是有没有更简洁的方法?即

var top = new string[]  "Crusty bread", "Mayonnaise" ;
string filling = "BTL";
var bottom = new string[]  "Mayonnaise", "Crusty bread" ;

// Will not compile, filling is a string, therefore is not Enumerable
//var sandwich = top.Union(filling).Union(bottom);

// Compiles and works, but feels grungy (looks like it might be smelly)
var sandwich = top.Union(new string[]filling).Union(bottom);

foreach (var item in sandwich)
    Process(item);

是否有一种批准的方式来做到这一点,或者这是批准的方式?

谢谢

【问题讨论】:

这就是我倾向于这样做的方式.. 不开心,但从未想过值得解决.. 想知道是否有办法在 T 和 T 数组之间编写隐式转换.. Favorite way to create an new IEnumerable<T> sequence from a single value? 的可能重复项 您可以通过将 new string[] 简化为 new[] 来稍微简化联合表达式。否则,如果您最终经常这样做,Jon Hanna 的解决方案可能是解决此问题的最佳方法。 【参考方案1】:

一种选择是自己重载它:

public static IEnumerable<T> Union<T>(this IEnumerable<T> source, T item)

    return source.Union(Enumerable.Repeat(item, 1));

这就是我们在MoreLINQ 中对Concat 所做的。

【讨论】:

Enumerable.Repeat,完美,谢谢。我可能确实会使用那个重载,谢谢。 对于额外的书呆子,将重载命名为cons:D 在编写 C# 代码时,我发现自己经常渴望使用 F# 或 LISP 等语言的集合操作运算符。像list :: itemlist1 @ list2 这样的语法,一旦你习惯了它们,就会变得非常易读。【参考方案2】:

考虑使用更灵活的方法:

public static IEnumerable<T> Union<T>(this IEnumerable<T> source, params T[] items)

    return source.Union((IEnumerable<T>)items);

适用于单个和多个项目。 您也可以接受 null source 值:

public static IEnumerable<T> Union<T>(this IEnumerable<T> source, params T[] items)

    return source != null ? source.Union((IEnumerable<T>)items) : items;

【讨论】:

【参考方案3】:

.NET Core 和 .NET Framework 4.7.1 版支持的新方法是使用 Append 扩展方法。

这将使您的代码像

一样简单优雅
var sandwich = top.Append(filling).Union(bottom);

【讨论】:

【参考方案4】:

我倾向于在我的代码中包含以下内容:

public static IEnumerable<T> EmitFromEnum<T>(this T item)

  yield return item;

虽然调用col.Union(obj.EmitFromEnum()); 不像col.Union(obj) 那样简洁,但这确实意味着这个单一的扩展方法涵盖了我可能想要这样一个单项枚举的所有其他情况。

更新:使用 .NET Core,您现在可以使用 .Append().Prepend() 将单个元素添加到可枚举。该实现经过优化以避免在后台生成过多的IEnumerator 实现。

【讨论】:

public static IEnumerable&lt;T&gt; EmitFromEnum&lt;T&gt;(this T item) yield return item; @KuganKumar 是的。谢谢。

以上是关于是否有更简洁的 linq 方式来“联合”单个项目?的主要内容,如果未能解决你的问题,请参考以下文章

Python 是不是有更简洁的方式来表达“如果 x 包含 a|b|c|d...”? [复制]

是否有更简洁的方法来获取错误和 Promise 的结果 [重复]

c# - 是不是有更简洁的方法来检查变量是不是是多个事物之一?

是否有一种较少冗余的方式来加载/保存实体?

定义默认数组值的最简洁方式

联合运营商的Linq查询返回错误