我需要在IEnumerable之前添加一个值(在本例中为IEnumerable<string[]>
)。为了做到这一点,我创建一个List<T>
只是为了包装第一个值,以便我可以调用Concat
:
// get headers and data together
IEnumerable<string[]> headers = new List<string[]> {
GetHeaders()
};
var all = headers.Concat(GetData());
呸。有没有更好的办法?你会如何处理附加值的相反情况呢?
答案 0 :(得分:23)
我编写了自定义扩展方法来执行此操作:
public static IEnumerable<T> Append<T>(this IEnumerable<T> source, T item)
{
foreach (T i in source)
yield return i;
yield return item;
}
public static IEnumerable<T> Prepend<T>(this IEnumerable<T> source, T item)
{
yield return item;
foreach (T i in source)
yield return i;
}
在你的场景中,你会写:
var all = GetData().Prepend(GetHeaders());
正如chilltemp评论的那样,这不会改变原始集合。以真正的Linq方式,它会生成一个新的IEnumerable<T>
。
注意: 建议source
进行急切的空参数检查,但为简洁起见,不会显示。
答案 1 :(得分:7)
使用Enumerable.Concat扩展名方法。要附加值而不是前置,您只需反向调用Concat
即可。 (即:GetData().Concat(GetHeaders());
)
如果GetHeaders()
返回单个字符串数组,我个人可能将其包装在单个元素数组而不是列表中:
var all = (new[] {GetHeaders()}).Concat(GetData());
答案 2 :(得分:1)
Rx包含StartWith方法,该方法将值添加到序列之前。此外,Return可以将值包装为序列,因此可以通过Concat附加。
var c = new[] {4};
var c1 = c.StartWith(1, 2, 3);
var c2 = c1.Concat(EnumerableEx.Return(5));
c2.Run(Console.Write); // 12345
答案 3 :(得分:0)
另一个选项是辅助方法,它可以从单个项目中创建序列:
public static class EnumerableExt
{
public static IEnumerable<T> One<T>(T item)
{
yield return item;
}
}
...
//prepend:
EnumerableExt.One( GetHeaders() ).Concat( GetData() );
//append:
GetData().Concat( EnumerableExt.One( GetHeaders() );
答案 4 :(得分:0)