【问题标题】:Concatenate a range of a List<string>连接 List<string> 的范围
【发布时间】:2020-05-17 10:58:07
【问题描述】:

如果我有一个List&lt;string&gt;,并且我想从列表中的所有 元素创建一个string,我可以使用Join 或Aggregate 来完成,如下所示那个。

var list = new List<string>() { "A", "B", "C", "D", "E" };
var concatAllByJoin = string.Join(string.Empty, list);
var concatAllByAggregate = list.Aggregate((a, b) => a + b);

两者都会产生字符串ABCDE。

如果我想做同样的事情,但只针对列表中的某个范围。说,我想连接索引 1 和 3 之间的项目。换句话说,我希望结果是BCD。

我能想到的一种方法是像这样使用GetRange():

var concatRange = string.Join(string.Empty, list.GetRange(1, 3));

这显然有效,但问题是数据重复。我很想知道是否有办法在不重复的情况下做到这一点。

【问题讨论】:

  • 数据重复是什么意思?
  • 你在使用 .NET Core 3 吗?
  • GetRange() 不创建新列表吗?
  • @maccettura 不,它是 .NET 常规框架。确切地说是 4.7。
  • GetRange() 返回源 List&lt;T&gt; 中一系列元素的浅表副本。

标签: c# string concatenation aggregate


【解决方案1】:

您可以为此使用StringBuilder

var list = new List<string>() { "A", "B", "C", "D", "E" };

var builder = new StringBuilder();
for (int i = 1; i <= 3; i++)
{
    builder.Append(list[i]);
}

var concatRange = builder.ToString();

它不会创建源列表的任何副本 - 您只需通过索引访问元素并将它们添加到 StringBuilder。 您还可以通过指定capacity值,在构造函数中传递来指定最大项目数(可以存储在StringBuilder实例分配的内存中)。

与Linq 解决方案相比的性能基准。 我不认为它们非常准确,因为源列表太小,但性能差异很大。

【讨论】:

    【解决方案2】:

    如果你这样做:

    var concatRange = string.Join(string.Empty, list.Skip(1).Take(3));
    

    您将不会创建另一个列表实例。但是对于小型集合,我认为您会发现额外的列表并不像枚举器那样昂贵,而且可能效率更高。请记住,列表元素只存储引用,因此字符串值本身不会被复制。

    【讨论】:

    • 这可能就是我想要的。是的,我知道我可以使用GetRange(),因为我可能不会连接 10 万个项目,主要想知道它是否可以完成。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-02-06
    • 2017-06-09
    • 1970-01-01
    • 1970-01-01
    • 2016-02-23
    • 1970-01-01
    相关资源
    最近更新 更多