将单个值附加或预先添加到IEnumerable <t>的简单方法是什么?</t>

时间:2010-08-04 18:29:21

标签: c# linq ienumerable

我需要在IEnumerable之前添加一个值(在本例中为IEnumerable<string[]>)。为了做到这一点,我创建一个List<T>只是为了包装第一个值,以便我可以调用Concat

// get headers and data together
IEnumerable<string[]> headers = new List<string[]> {
    GetHeaders()
};
var all = headers.Concat(GetData());

呸。有没有更好的办法?你会如何处理附加值的相反情况呢?

5 个答案:

答案 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)

.NET 4.7.1和更高版本中最简单,最干净的方法是使用无副作用的Prepend()Append()

示例

// Creating an array of numbers
var numbers = new[] { 1, 2, 3 };

// Prepend and Append any value of the same type
var results = numbers.Prepend(0).Append(4);

// output is 0, 1, 2, 3, 4
Console.WriteLine(string.Join(", ", results ));