如何在字符串上使用`.Take()`并获取一个字符串作为结果?

27

LINQ支持对字符串对象进行查询,但当我使用以下代码时:

string SomeText = "this is some text in a string";
return SomeText.Take(6).ToString();

我得到的全部信息是:

System.Linq.Enumerable+<TakeIterator>d__3a`1[System.Char]

这个问题在这个问答中被称为“意外情况”,但实际上这正是我想要尝试的,我无法通过搜索找到它的解决方案。

我知道有其他方法可以操作字符串,但我也知道你可以用LINQ做一些非常酷的技巧,我只想知道是否有一种使用LINQ将字符串截断到特定长度的方法?

6个回答

23

System.Linq中没有内置方法来完成此操作,但您可以相当容易地编写自己的扩展方法:

public static class StringExtensions
{
    public static string ToSystemString(this IEnumerable<char> source)
    {
        return new string(source.ToArray());
    }
}

很遗憾,因为所有 .NET 对象上都存在 object.ToString,所以您必须给该方法取一个不同的名称,以便编译器调用您的扩展方法而不是内置的 ToString

根据您下面的评论,质疑这是否是正确的方法是好的。因为 String 通过其公共方法公开了许多功能,我建议将此方法实现为 String 自身的扩展。

/// <summary>
/// Truncates a string to a maximum length.
/// </summary>
/// <param name="value">The string to truncate.</param>
/// <param name="length">The maximum length of the returned string.</param>
/// <returns>The input string, truncated to <paramref name="length"/> characters.</returns>
public static string Truncate(this string value, int length)
{
    if (value == null)
        throw new ArgumentNullException("value");
    return value.Length <= length ? value : value.Substring(0, length);
}
你可以按以下方式使用它:
string SomeText = "this is some text in a string";
return SomeText.Truncate(6);

这种方法的优点是,当字符串已经短于所需长度时,不会创建任何临时数组/对象。


谢谢。这是做事情的“好”方法吗?它是一个更大系统的一部分,我正在传递一个StringBuilder,并.Append()了很多数据以生成文件。我知道我不应该过早地优化,但是按照您建议的使用LINQ,是否会在有更简单的方法时浪费大量cpu/内存?简单地说:您会在自己的项目中使用此代码将字符串裁剪到特定长度吗? - rtpHarry
1
@rtpHarry 很好的问题;我个人不会使用LINQ来完成这个任务,并已更新我的答案,提供我会选择的方法。 - Bradley Grainger
谢谢您的额外反馈,我会根据此更新我的代码 :) - rtpHarry

23

只需创建字符串即可

string res = new string(SomeText.Take(6).ToArray());

同时注意字符串的内置方法。

string res = SomeText.Substring(0, 6);

4
如果SomeText长度小于六个字符,子字符串会抛出异常;我假设原帖作者想要一个类似于Take行为的方法(即最多返回相应数量的字符,但如果输入字符串较短,则返回更少的字符,而不是抛出异常)。 - Bradley Grainger

8
我曾多次遇到此问题并采用以下解决方法:
string.Join(string.Empty,yourString.Take(5));

4

SomeText.Take(6)会返回一个字符的IEnumerable,而ToString方法不会返回你需要的字符串,你需要像下面这样调用它:

string [] array = SomeText.Take(6).ToArray();
string result = new string(array);

0

我在查找关于LINQ和字符串的信息时发现了这个问题。

您可以使用IEnumerable<char>代替string作为返回数据类型。 您还可以在如何查询字符串中的字符(LINQ)(C#)中了解更多相关信息。

以下是解决方案。

public class Program
{
    public static void Main()
    {
        foreach (var c in LinqString())
        {
            Console.WriteLine(c);
        }
        //OR
        Console.WriteLine(LinqString().ToArray());
    }

    private static IEnumerable<char> LinqString()
    {
        //This is Okay too...
        //IEnumerable<char> SomeText = "this is some text in a string";

        string SomeText = "this is some text in a string";
        
        return SomeText.Skip(4).Take(6);
    }
}

0

使用C# 8及更高版本...

获取最后6位数字(如果输入少于8个字符,则失败

string SomeText = "this is some text in a string";
string result =  SomeText[^6..];

一个受保护的版本,可以处理少于6个字符的字符串...

string SomeText = "this is some text in a string";
string result = SomeText[^(Math.Min(6, SomeText.Length))..];

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接