Pertanyaan int array ke string


Dalam C #, saya memiliki array int, yang hanya berisi digit. Saya ingin mengubah array ini menjadi string.

Contoh array:

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

Bagaimana saya bisa mengonversinya ke string yang diformat sebagai: "012301"?


47
2017-11-30 22:20


asal


Jawaban:


at.net 3.5 gunakan:

 String.Join("", new List<int>(array).ConvertAll(i => i.ToString()).ToArray());

at.net 4.0 atau di atas digunakan: (lihat jawaban @Jan Remunda)

 string result = string.Join("", array);

75
2017-11-30 22:22



Saya menyadari pendapat saya mungkin bukan yang populer, tapi saya kira saya memiliki waktu yang sulit melompat di gerobak band Linq-y. Ini bagus. Itu kental. Saya mengerti itu dan saya tidak menentang untuk menggunakannya di tempat yang tepat. Mungkin itu hanya saya, tapi saya merasa seperti orang telah berhenti berpikir tentang membuat fungsi utilitas untuk mencapai apa yang mereka inginkan dan lebih suka mengotori kode mereka dengan (kadang-kadang) baris kode Linq terlalu panjang demi menciptakan 1-liner padat.

Saya tidak mengatakan bahwa salah satu jawaban Linq yang diberikan orang di sini buruk, tapi saya rasa saya merasa ada potensi bahwa satu baris kode ini dapat mulai tumbuh lebih lama dan lebih tidak jelas karena Anda perlu menangani berbagai situasi . Bagaimana jika array Anda tidak? Bagaimana jika Anda menginginkan string terbatas, bukan hanya rangkaian murni? Bagaimana jika beberapa bilangan bulat dalam larik Anda adalah dua digit dan Anda ingin menyisipkan setiap nilai dengan nol terkemuka sehingga string untuk setiap elemen memiliki panjang yang sama dengan yang lainnya?

Mengambil salah satu jawaban yang disediakan sebagai contoh:

        result = arr.Aggregate(string.Empty, (s, i) => s + i.ToString());

Jika saya perlu khawatir tentang array yang null, sekarang menjadi ini:

        result = (arr == null) ? null : arr.Aggregate(string.Empty, (s, i) => s + i.ToString());

Jika saya ingin string yang dipisahkan koma, sekarang menjadi ini:

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

Ini masih belum terlalu buruk, tapi saya pikir itu tidak jelas dalam sekejap apa yang sedang dilakukan kode baris ini.

Tentu saja, tidak ada yang menghentikan Anda dari melemparkan baris kode ini ke dalam fungsi utilitas Anda sendiri sehingga Anda tidak memiliki kekacauan panjang bercampur dengan logika aplikasi Anda, terutama jika Anda melakukannya di banyak tempat:

    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());
    }

Tetapi jika Anda akan memasukkannya ke dalam fungsi utilitas, apakah Anda benar-benar membutuhkannya untuk dikondisikan menjadi 1-liner? Dalam hal itu mengapa tidak menambahkan beberapa baris tambahan untuk kejelasan dan mengambil keuntungan dari StringBuilder sehingga Anda tidak melakukan operasi penggabungan berulang:

    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;
        }
    }

Dan jika Anda sangat memperhatikan kinerja, Anda bahkan dapat mengubahnya menjadi fungsi hibrida yang memutuskan apakah akan melakukan string.Gabung atau gunakan StringBuilder tergantung pada berapa banyak elemen dalam array (ini adalah mikro-optimasi, tidak layak dilakukan menurut saya dan mungkin lebih berbahaya daripada bermanfaat, tapi saya menggunakannya sebagai contoh untuk masalah ini):

    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;
        }
    }

Untuk contoh ini, dampak kinerja mungkin tidak layak diperhatikan, tetapi intinya adalah bahwa jika Anda berada dalam situasi di mana Anda benar-benar perlu khawatir dengan kinerja operasi Anda, apa pun itu, maka kemungkinan besar akan menjadi lebih mudah dan lebih mudah dibaca untuk menangani itu dalam fungsi utilitas daripada menggunakan ekspresi Linq yang kompleks.

Fungsi utilitas itu masih terlihat agak kikuk. Sekarang mari kita membuang hal-hal hibrida dan melakukan ini:

    // 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);
    }

Sekarang kita memiliki fungsi utilitas yang terpisah dan cukup kompak, yang masing-masing dapat digunakan sendiri.

Pada akhirnya, poin saya bukanlah bahwa Anda tidak harus menggunakan Linq, tetapi hanya untuk mengatakan jangan lupa tentang manfaat menciptakan fungsi utilitas Anda sendiri, bahkan jika mereka kecil dan mungkin hanya berisi satu baris yang mengembalikan hasil dari baris kode Linq. Jika tidak ada yang lain, Anda akan dapat menjaga kode aplikasi Anda lebih kental daripada yang bisa Anda capai dengan baris kode Linq, dan jika Anda menggunakannya di banyak tempat, kemudian menggunakan fungsi utilitas membuatnya lebih mudah untuk menyesuaikan output Anda jika Anda perlu mengubahnya nanti.

Untuk masalah ini, saya lebih suka menulis sesuatu seperti ini di kode aplikasi saya:

        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');

24
2017-12-01 01:03



Anda cukup menggunakan String.Join fungsi dan sebagai pemisah menggunakan string kosong Ini secara internal menggunakan StringBuilder.

string result = string.Join(string.Emtpy, new []{0,1,2,3,0,1});

Misalnya: Jika Anda menggunakan sebagai titik koma pemisah, hasilnya adalah: "0; 1; 2; 3; 0; 1". Ini benar-benar bekerja dengan pemisah nol dan parameter kedua dapat beragam objek, seperti:

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

23
2018-04-05 07:47



Untuk menghindari pembuatan susunan ekstra Anda bisa melakukan hal berikut.

var builder = new StringBuilder();
Array.ForEach(arr, x => builder.Append(x));
var res = builder.ToString();

20
2017-11-30 22:23



string result = arr.Aggregate("", (s, i) => s + i.ToString());

(Penafian: Jika Anda memiliki banyak digit (ratusan, setidaknya) dan Anda peduli dengan kinerja, saya sarankan untuk menghindari metode ini dan menggunakan StringBuilder, seperti jawaban JaredPar.)


9
2017-11-30 22:22



Anda dapat melakukan:

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

Itu memberi Anda hasil Anda.


5
2017-11-30 22:22



Saya suka menggunakan StringBuilder dengan Aggregate(). "Trik" -nya itu Append() mengembalikan StringBuilder instance itu sendiri:

var sb = arr.Aggregate( new StringBuilder(), ( s, i ) => s.Append( i ) );
var result = sb.ToString();     

5
2017-11-30 22:36