Преобразование разделенных запятыми строк ints в массив int
Я нашел способ сделать это наоборот: создать строку, разделенную запятыми, из списка или массива int, но не о том, как преобразовать входные данные, такие как string str = "1,2,3,4,5";
, в массив или список int.
Вот моя реализация (вдохновленная этим сообщением Эриком Липпертом):
public static IEnumerable<int> StringToIntList(string str)
{
if (String.IsNullOrEmpty(str))
{
yield break;
}
var chunks = str.Split(',').AsEnumerable();
using (var rator = chunks.GetEnumerator())
{
while (rator.MoveNext())
{
int i = 0;
if (Int32.TryParse(rator.Current, out i))
{
yield return i;
}
else
{
continue;
}
}
}
}
Считаете ли вы, что это хороший подход или есть более простой, возможно, даже встроенный способ?
РЕДАКТИРОВАТЬ: Извините за любую путаницу, но метод должен обрабатывать недопустимый ввод типа "1,2,,,3"
или "###, 5,"
и т.д., пропустив его.
Ответы
Ответ 1
Вы должны использовать цикл foreach, например:
public static IEnumerable<int> StringToIntList(string str) {
if (String.IsNullOrEmpty(str))
yield break;
foreach(var s in str.Split(',')) {
int num;
if (int.TryParse(s, out num))
yield return num;
}
}
Обратите внимание, что, как и ваш исходный пост, это игнорирует числа, которые не могут быть проанализированы.
Если вы хотите выбросить исключение, если число не может быть проанализировано, вы можете сделать это гораздо проще с помощью LINQ:
return (str ?? "").Split(',').Select<string, int>(int.Parse);
Ответ 2
Если вы не хотите иметь текущее поведение обработки ошибок, это очень просто:
return text.Split(',').Select(x => int.Parse(x));
В противном случае я бы использовал дополнительный вспомогательный метод (как видно сегодня утром):
public static int? TryParseInt32(string text)
{
int value;
return int.TryParse(text, out value) ? value : (int?) null;
}
и
return text.Split(',').Select<string, int?>(TryParseInt32)
.Where(x => x.HasValue)
.Select(x => x.Value);
или если вы не хотите использовать преобразование группы методов:
return text.Split(',').Select(t => t.TryParseInt32(t)
.Where(x => x.HasValue)
.Select(x => x.Value);
или в форме выражения запроса:
return from t in text.Split(',')
select TryParseInt32(t) into x
where x.HasValue
select x.Value;
Ответ 3
Без использования лямбда-функции и только для действительных входов я думаю, что это яснее:
Array.ConvertAll<string, int>(value.Split(','), Convert.ToInt32);
Ответ 4
- ИЗМЕНИТЬ - Похоже, я слишком буквально взял его вопрос, он спрашивал массив ints, а не List --EDIT ENDS -
Еще один вспомогательный метод...
private static int[] StringToIntArray(string myNumbers)
{
List<int> myIntegers = new List<int>();
Array.ForEach(myNumbers.Split(",".ToCharArray()), s =>
{
int currentInt;
if (Int32.TryParse(s, out currentInt))
myIntegers.Add(currentInt);
});
return myIntegers.ToArray();
}
быстрый тестовый код для него тоже...
static void Main(string[] args)
{
string myNumbers = "1,2,3,4,5";
int[] myArray = StringToIntArray(myNumbers);
Console.WriteLine(myArray.Sum().ToString()); // sum is 15.
myNumbers = "1,2,3,4,5,6,bad";
myArray = StringToIntArray(myNumbers);
Console.WriteLine(myArray.Sum().ToString()); // sum is 21
Console.ReadLine();
}
Ответ 5
Это было задано раньше..Net имеет встроенную функцию ConvertAll для преобразования между массивом одного типа в массив другого типа. Вы можете комбинировать это с Split для разделения строки на массив строк
Пример функции:
static int[] ToIntArray(this string value, char separator)
{
return Array.ConvertAll(value.Split(separator), s=>int.Parse(s));
}
Взято отсюда
Ответ 6
Это для longs, но вы можете легко его модифицировать для работы с ints.
private static long[] ConvertStringArrayToLongArray(string str)
{
return str.Split(",".ToCharArray()).Select(x => long.Parse(x.ToString())).ToArray();
}
Ответ 7
Я не понимаю, почему выключение перечислителя явно дает вам преимущество перед использованием foreach
. Также не нужно называть AsEnumerable
на chunks
.
Ответ 8
Я думаю, это достаточно хорошо. Ясно, что он ленив, поэтому он будет быстрым (за исключением, может быть, первого случая, когда вы разделите строку).
Ответ 9
Я увлекаюсь простым решением, которое сработало для меня.
String.Join(",",str.Split(','));