int数组到字符串

use*_*232 55 c# arrays string

在C#中,我有一个int数组,只包含数字.我想将此数组转换为字符串.

数组示例:

int[] arr = {0,1,2,3,0,1};
Run Code Online (Sandbox Code Playgroud)

如何将其转换为格式为的字符串:"012301"

JSB*_*ոգչ 88

at.net 3.5使用:

 String.Join("", new List<int>(array).ConvertAll(i => i.ToString()).ToArray());
Run Code Online (Sandbox Code Playgroud)

at.net 4.0或以上使用:(参见@Jan Remunda的回答)

 string result = string.Join("", array);
Run Code Online (Sandbox Code Playgroud)

  • 有很多不必要的代码:)尝试只是:String.Join("",new int [] {0,1,2,3,0,1}); (4认同)

Jan*_*nda 27

您可以简单地使用String.Join函数并作为分隔符使用,string.Empty因为它在内部使用StringBuilder.

string result = string.Join(string.Empty, new []{0,1,2,3,0,1});
Run Code Online (Sandbox Code Playgroud)

例如:如果使用分号作为分隔符,结果将是StringBuilder.它实际上使用null分隔符,第二个参数可以枚举任何对象,如:

string result = string.Join(null, new object[]{0,1,2,3,0,"A",DateTime.Now});
Run Code Online (Sandbox Code Playgroud)

  • 此解决方案适用于.NET 4.0及更高版本 (8认同)

Dr.*_*ice 24

我意识到我的观点可能不是很受欢迎,但我想我很难跳上Linq-y乐队的旅行车.这很漂亮.它凝聚了.我明白了,我并不反对在合适的地方使用它.也许这只是我,但我觉得人们已经不再考虑创建实用功能来实现他们想要的东西,而是倾向于使用(有时)过长的Linq代码来为了创建一个密集的1-liner而丢弃他们的代码.

我不是说人们在这里提供的任何Linq答案都很糟糕,但我想我觉得这些单行代码有可能开始变得更长,更难以理解,因为你需要处理各种情况.如果你的数组为空怎么办?如果你想要一个分隔的字符串而不是纯粹的连接怎么办?如果数组中的某些整数是两位数并且您希望用前导零填充每个值,以便每个元素的字符串与其余元素的长度相同,该怎么办?

以提供的答案之一为例:

        result = arr.Aggregate(string.Empty, (s, i) => s + i.ToString());
Run Code Online (Sandbox Code Playgroud)

如果我需要担心数组为null,现在它变为:

        result = (arr == null) ? null : arr.Aggregate(string.Empty, (s, i) => s + i.ToString());
Run Code Online (Sandbox Code Playgroud)

如果我想要一个以逗号分隔的字符串,现在它变为:

        result = (arr == null) ? null : arr.Skip(1).Aggregate(arr[0].ToString(), (s, i) => s + "," + i.ToString());
Run Code Online (Sandbox Code Playgroud)

这仍然不是太糟糕,但我认为这一行代码正在做什么并不明显.

当然,没有什么可以阻止你将这行代码放入你自己的实用程序函数中,这样你就不会在应用程序逻辑中混入那么长的混乱,特别是如果你在多个地方都这样做:

    public static string ToStringLinqy<T>(this T[] array, string delimiter)
    {
        // edit: let's replace this with a "better" version using a StringBuilder
        //return (array == null) ? null : (array.Length == 0) ? string.Empty : array.Skip(1).Aggregate(array[0].ToString(), (s, i) => s + "," + i.ToString());
        return (array == null) ? null : (array.Length == 0) ? string.Empty : array.Skip(1).Aggregate(new StringBuilder(array[0].ToString()), (s, i) => s.Append(delimiter).Append(i), s => s.ToString());
    }
Run Code Online (Sandbox Code Playgroud)

但是如果你打算把它变成一个实用功能,你真的需要将它浓缩成一个单行程吗?在这种情况下,为什么不为了清晰而抛出一些额外的行并利用StringBuilder,这样你就不会重复连接操作:

    public static string ToStringNonLinqy<T>(this T[] array, string delimiter)
    {
        if (array != null)
        {
            // edit: replaced my previous implementation to use StringBuilder
            if (array.Length > 0)
            {
                StringBuilder builder = new StringBuilder();

                builder.Append(array[0]);
                for (int i = 1; i < array.Length; i++)
                {
                    builder.Append(delimiter);
                    builder.Append(array[i]);
                }

                return builder.ToString()
            }
            else
            {
                return string.Empty;
            }
        }
        else
        {
            return null;
        }
    }
Run Code Online (Sandbox Code Playgroud)

如果你真的非常关心性能,你甚至可以将它变成一个混合函数,决定是否要执行string.Join或使用StringBuilder,具体取决于数组中有多少元素(这是一个微优化,在我看来不值得做,可能比有益更有害,但我用它作为这个问题的一个例子):

    public static string ToString<T>(this T[] array, string delimiter)
    {
        if (array != null)
        {
            // determine if the length of the array is greater than the performance threshold for using a stringbuilder
            // 10 is just an arbitrary threshold value I've chosen
            if (array.Length < 10)
            {
                // assumption is that for arrays of less than 10 elements
                // this code would be more efficient than a StringBuilder.
                // Note: this is a crazy/pointless micro-optimization.  Don't do this.
                string[] values = new string[array.Length];

                for (int i = 0; i < values.Length; i++)
                    values[i] = array[i].ToString();

                return string.Join(delimiter, values);
            }
            else
            {
                // for arrays of length 10 or longer, use a StringBuilder
                StringBuilder sb = new StringBuilder();

                sb.Append(array[0]);
                for (int i = 1; i < array.Length; i++)
                {
                    sb.Append(delimiter);
                    sb.Append(array[i]);
                }

                return sb.ToString();
            }
        }
        else
        {
            return null;
        }
    }
Run Code Online (Sandbox Code Playgroud)

对于这个例子,性能影响可能不值得关注,但关键在于,如果您确实需要关注您的操作性能,无论它们是什么,那么它很可能是在实用程序函数中处理它比使用复杂的Linq表达式更容易和更易读.

那个效用函数看起来仍然很笨重.现在让我们抛弃混合物并做到这一点:

    // convert an enumeration of one type into an enumeration of another type
    public static IEnumerable<TOut> Convert<TIn, TOut>(this IEnumerable<TIn> input, Func<TIn, TOut> conversion)
    {
        foreach (TIn value in input)
        {
            yield return conversion(value);
        }
    }

    // concatenate the strings in an enumeration separated by the specified delimiter
    public static string Delimit<T>(this IEnumerable<T> input, string delimiter)
    {
        IEnumerator<T> enumerator = input.GetEnumerator();

        if (enumerator.MoveNext())
        {
            StringBuilder builder = new StringBuilder();

            // start off with the first element
            builder.Append(enumerator.Current);

            // append the remaining elements separated by the delimiter
            while (enumerator.MoveNext())
            {
                builder.Append(delimiter);
                builder.Append(enumerator.Current);
            }

            return builder.ToString();
        }
        else
        {
            return string.Empty;
        }
    }

    // concatenate all elements
    public static string ToString<T>(this IEnumerable<T> input)
    {
        return ToString(input, string.Empty);
    }

    // concatenate all elements separated by a delimiter
    public static string ToString<T>(this IEnumerable<T> input, string delimiter)
    {
        return input.Delimit(delimiter);
    }

    // concatenate all elements, each one left-padded to a minimum length
    public static string ToString<T>(this IEnumerable<T> input, int minLength, char paddingChar)
    {
        return input.Convert(i => i.ToString().PadLeft(minLength, paddingChar)).Delimit(string.Empty);
    }
Run Code Online (Sandbox Code Playgroud)

现在我们有了独立且相当紧凑的实用函数,每个函数都可以自己论证.

最后,我的观点并不是你不应该使用Linq,而只是说不要忘记创建自己的实用程序函数的好处,即使它们很小并且可能只包含一行返回结果一行Linq代码.如果没有别的,你将能够保持你的应用程序代码比使用一系列Linq代码更加精简,如果你在多个地方使用它,那么使用实用程序功能可以更容易地调整输出如果您以后需要更改它.

对于这个问题,我宁愿在我的应用程序代码中写这样的东西:

        int[] arr = { 0, 1, 2, 3, 0, 1 };

        // 012301
        result = arr.ToString<int>();

        // comma-separated values
        // 0,1,2,3,0,1
        result = arr.ToString(",");

        // left-padded to 2 digits
        // 000102030001
        result = arr.ToString(2, '0');
Run Code Online (Sandbox Code Playgroud)


Jar*_*Par 20

为避免创建额外的数组,您可以执行以下操作.

var builder = new StringBuilder();
Array.ForEach(arr, x => builder.Append(x));
var res = builder.ToString();
Run Code Online (Sandbox Code Playgroud)

  • 史蒂夫,好主意,但这不会起作用,因为`ForEach()`期望`void`,`Append()`返回`StringBuilder`. (3认同)

mqp*_*mqp 10

string result = arr.Aggregate("", (s, i) => s + i.ToString());
Run Code Online (Sandbox Code Playgroud)

(免责声明:如果你有很多数字(数百,至少)并且你关心性能,我建议避免这种方法并使用a StringBuilder,如JaredPar的答案.)

  • 这实际上看起来很昂贵.这具有"伸缩"的内存要求,因此对于小型阵列上的任何东西都不理想.抱歉. (8认同)

Ree*_*sey 5

你可以做:

 int[] arr = {0,1,2,3,0,1};
 string results = string.Join("",arr.Select(i => i.ToString()).ToArray());
Run Code Online (Sandbox Code Playgroud)

这会给你你的结果.


Dan*_*bić 5

我喜欢用StringBuilderAggregate()."技巧"是Append()返回StringBuilder实例本身:

var sb = arr.Aggregate( new StringBuilder(), ( s, i ) => s.Append( i ) );
var result = sb.ToString();     
Run Code Online (Sandbox Code Playgroud)