У меня есть массив целых чисел:
int[] number = new int[] { 2,3,6,7 };
Как проще всего преобразовать их в одну строку, в которой числа разделены символом (например: "2,3,6,7" ?
Я использую C # и .NET 3.5.
У меня есть массив целых чисел:
int[] number = new int[] { 2,3,6,7 };
Как проще всего преобразовать их в одну строку, в которой числа разделены символом (например: "2,3,6,7" ?
Я использую C # и .NET 3.5.
.NET 4.0существуют методы , которые принимают массив объектов и IEnumerable , так что вы можете просто сделать string.join(",", number). Я знаю, что в вопросе указывается .NET 3.5, поэтому я не дал этого ответа, но он появляется при поиске, в котором не указывается версия, и знание того, что это возможно в 4.0, может кому-то помочь.
Ответы:
var ints = new int[] {1, 2, 3, 4, 5};
var result = string.Join(",", ints.Select(x => x.ToString()).ToArray());
Console.WriteLine(result); // prints "1,2,3,4,5"
РЕДАКТИРОВАТЬ : Начиная с (по крайней мере) .NET 4.5,
var result = string.Join(",", ints.Select(x => x.ToString()).ToArray());
эквивалентно:
var result = string.Join(",", ints);
ИЗМЕНИТЬ :
Я вижу, что несколько решений рекламируют использование StringBuilder. Кто-то жалуется, что метод Join должен принимать аргумент IEnumerable.
Я вас разочарую :) String.Join требует массив только по одной причине - производительности. Метод соединения должен знать размер данных, чтобы эффективно предварительно выделить необходимый объем памяти.
Вот часть внутренней реализации метода String.Join:
// length computed from length of items in input array and length of separator
string str = FastAllocateString(length);
fixed (char* chRef = &str.m_firstChar) // note than we use direct memory access here
{
UnSafeCharBuffer buffer = new UnSafeCharBuffer(chRef, length);
buffer.AppendString(value[startIndex]);
for (int j = startIndex + 1; j <= num2; j++)
{
buffer.AppendString(separator);
buffer.AppendString(value[j]);
}
}
Мне лень сравнивать производительность предложенных методов. Но что-то мне подсказывает, что победит Join :)
using System.Linq;необходимо.
Хотя OP указал .NET 3.5, люди, желающие сделать это в .NET 2.0 с C # 2, могут сделать это:
string.Join(",", Array.ConvertAll<int, String>(ints, Convert.ToString));
Я обнаружил, что есть ряд других случаев, когда использование функций Convert.xxx является более изящной альтернативой лямбда-выражению, хотя в C # 3 лямбда-функция может помочь в определении типа.
Вот довольно компактная версия C # 3, которая работает с .NET 2.0:
string.Join(",", Array.ConvertAll(ints, item => item.ToString()))
Одним из сочетаний этих двух подходов было бы написание метода расширения в IEnumerable <T>, который использовал бы StringBuilder. Вот пример с разными перегрузками в зависимости от того, хотите ли вы указать преобразование или просто полагаться на простой ToString. Я назвал метод «JoinStrings» вместо «Join», чтобы избежать путаницы с другим типом Join. Может кто-нибудь придумает название получше :)
using System;
using System.Collections.Generic;
using System.Text;
public static class Extensions
{
public static string JoinStrings<T>(this IEnumerable<T> source,
Func<T, string> projection, string separator)
{
StringBuilder builder = new StringBuilder();
bool first = true;
foreach (T element in source)
{
if (first)
{
first = false;
}
else
{
builder.Append(separator);
}
builder.Append(projection(element));
}
return builder.ToString();
}
public static string JoinStrings<T>(this IEnumerable<T> source, string separator)
{
return JoinStrings(source, t => t.ToString(), separator);
}
}
class Test
{
public static void Main()
{
int[] x = {1, 2, 3, 4, 5, 10, 11};
Console.WriteLine(x.JoinStrings(";"));
Console.WriteLine(x.JoinStrings(i => i.ToString("X"), ","));
}
}
String.Join(";", number.Select(item => item.ToString()).ToArray());
Мы должны преобразовать каждый из элементов в a, Stringпрежде чем мы сможем присоединиться к ним, поэтому имеет смысл использовать Selectи лямбда-выражение. Это эквивалентно mapнекоторым другим языкам. Затем мы должны преобразовать полученную коллекцию строк обратно в массив, потому чтоString.Join принимает только массив строк.
ToArray()Немного некрасиво , я думаю. String.Joinдействительно должен принять IEnumerable<String>, нет причин ограничивать его только массивами. Вероятно, это просто потому, что Joinэто еще не все, когда массивы были единственным доступным типом коллекции.
Если ваш массив целых чисел может быть большим, вы получите лучшую производительность, используя StringBuilder. Например:
StringBuilder builder = new StringBuilder();
char separator = ',';
foreach(int value in integerArray)
{
if (builder.Length > 0) builder.Append(separator);
builder.Append(value);
}
string result = builder.ToString();
Изменить: когда я опубликовал это, у меня сложилось ошибочное впечатление, что «StringBuilder.Append (int value)» внутренне удалось добавить строковое представление целочисленного значения без создания строкового объекта. Это неправильно: проверка метода с помощью Reflector показывает, что он просто добавляет value.ToString ().
Поэтому единственное возможное различие в производительности заключается в том, что этот метод позволяет избежать создания одного массива и несколько быстрее освобождает строки для сборки мусора. На практике это не будет иметь никакого измеримого значения, поэтому я проголосовал за это лучшее решение .
Вопрос в том, чтобы «проще всего преобразовать их в одну строку, где числа разделены символом».
Самый простой способ:
int[] numbers = new int[] { 2,3,6,7 };
string number_string = string.Join(",", numbers);
// do whatever you want with your exciting new number string
EDIT: это работает только в .NET 4.0+, я пропустил требование .NET 3.5, когда впервые прочитал вопрос.
Я согласен с лямбда-выражением для удобства чтения и поддержки, но это не всегда будет лучшим вариантом. Обратной стороной использования обоих подходов IEnumerable / ToArray и StringBuilder является то, что они должны динамически увеличивать список, будь то элементы или символы, поскольку они не знают, сколько места потребуется для конечной строки.
Если это редкий случай, когда скорость важнее лаконичности, более эффективно следующее.
int[] number = new int[] { 1, 2, 3, 4, 5 };
string[] strings = new string[number.Length];
for (int i = 0; i < number.Length; i++)
strings[i] = number[i].ToString();
string result = string.Join(",", strings);
ints.Aggregate("", ( str, n ) => str +","+ n ).Substring(1);
Я тоже думал, что есть способ попроще. Не знаю о производительности, у кого-нибудь есть (теоретические) идеи?
Substring(1)чтобы исправить это (это было по памяти).
В .NET 4.0 у строкового соединения есть перегрузка params object[], поэтому это так просто, как:
int[] ids = new int[] { 1, 2, 3 };
string.Join(",", ids);
пример
int[] ids = new int[] { 1, 2, 3 };
System.Data.Common.DbCommand cmd = new System.Data.SqlClient.SqlCommand("SELECT * FROM some_table WHERE id_column IN (@bla)");
cmd.CommandText = cmd.CommandText.Replace("@bla", string.Join(",", ids));
В .NET 2.0 это немного сложнее, поскольку такой перегрузки нет. Итак, вам нужен собственный общий метод:
public static string JoinArray<T>(string separator, T[] inputTypeArray)
{
string strRetValue = null;
System.Collections.Generic.List<string> ls = new System.Collections.Generic.List<string>();
for (int i = 0; i < inputTypeArray.Length; ++i)
{
string str = System.Convert.ToString(inputTypeArray[i], System.Globalization.CultureInfo.InvariantCulture);
if (!string.IsNullOrEmpty(str))
{
// SQL-Escape
// if (typeof(T) == typeof(string))
// str = str.Replace("'", "''");
ls.Add(str);
} // End if (!string.IsNullOrEmpty(str))
} // Next i
strRetValue= string.Join(separator, ls.ToArray());
ls.Clear();
ls = null;
return strRetValue;
}
В .NET 3.5 вы можете использовать методы расширения:
public static class ArrayEx
{
public static string JoinArray<T>(this T[] inputTypeArray, string separator)
{
string strRetValue = null;
System.Collections.Generic.List<string> ls = new System.Collections.Generic.List<string>();
for (int i = 0; i < inputTypeArray.Length; ++i)
{
string str = System.Convert.ToString(inputTypeArray[i], System.Globalization.CultureInfo.InvariantCulture);
if (!string.IsNullOrEmpty(str))
{
// SQL-Escape
// if (typeof(T) == typeof(string))
// str = str.Replace("'", "''");
ls.Add(str);
} // End if (!string.IsNullOrEmpty(str))
} // Next i
strRetValue= string.Join(separator, ls.ToArray());
ls.Clear();
ls = null;
return strRetValue;
}
}
Таким образом, вы можете использовать метод расширения JoinArray.
int[] ids = new int[] { 1, 2, 3 };
string strIdList = ids.JoinArray(",");
Вы также можете использовать этот метод расширения в .NET 2.0, если вы добавите ExtensionAttribute в свой код:
// you need this once (only), and it must be in this namespace
namespace System.Runtime.CompilerServices
{
[AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Class | AttributeTargets.Method)]
public sealed class ExtensionAttribute : Attribute {}
}
Ты можешь сделать
ints.ToString(",")
ints.ToString("|")
ints.ToString(":")
Проверять, выписываться
Разделитель ToString с разделителями для массива, списка, словаря, универсального IEnumerable