如果我有以下字符串:
"123; 3344; 4334; 12"
我想在一个通用的这些数字List<int>,我想我不知道这里除了在循环分裂,做一个转换,然后添加到一个很好的方式List<int>,通过每一次迭代.有没有其他方法可以解决这个问题?
更新.这就是我想出来的.我想这样做旧时尚的方式,而不是使用LINQ,因为我试图让只用字符串,数组列表和操纵和一般转换更好.
public List<int> StringToList(string stringToSplit, char splitDelimiter)
{
List<int> list = new List<int>();
if (string.IsNullOrEmpty(stringToSplit))
return list;
string[] values = stringToSplit.Split(splitDelimiter);
if (values.Length <= 1)
return list;
foreach (string s in values)
{
int i;
if (Int32.TryParse(s, out i))
list.Add(i);
}
return list;
}
Run Code Online (Sandbox Code Playgroud)
这是我计划在每次需要将分隔的字符串列表转换为List时使用的新字符串实用程序方法
如果出现问题,我会将一个空列表返回给调用者.好坏?这样做很常见吗?
是的,有更多的"优雅"的方式与LINQ这样做,但我想这样做manually..the老办法,现在只是我自己的理解.
另外,困扰我的是:
list.AddRange(str.Split(';').Select(Int32.Parse));
Run Code Online (Sandbox Code Playgroud)
是我不知道的:
str.Split(';').Select(Int32.Parse)因为某种原因失败了怎么办......那么这个AddRange所处的方法会爆炸,除非我在整个事情中添加一个try/catch,如果我没有正确处理它,我就搞砸了.static int? ToInt32OrNull(string s)
{
int value;
return (Int32.TryParse(s, out value)) ? value : default(int?);
}
// ...
var str = "123;3344;4334;12";
var list = new List<int>();
list.AddRange(str.Split(';')
.Select(ToInt32OrNull)
.Where(i => i != null)
.Cast<int>());
Run Code Online (Sandbox Code Playgroud)
发问者说明:
除了在循环中拆分并进行转换然后添加到List之外,我不知道这里有什么好方法
一般来说,这是为什么LINQ被带入C#的一个主要原因 - 通过实现循环来消除处理值序列的需要,而只是声明你想要转换序列.如果你发现自己在想"除了循环之外我不知道如何做到这一点" - 现在是时候研究一个能为你完成工作的LINQ结构.
绩效更新:
LINQ的性能问题如下.虽然在评论中LINQ速度较慢的想法得到了保护,因为我们获得了可读性,可维护性和可组合性的好处,还有另一个方面为LINQ提供了一个简单的性能优势:并行性.这是一个添加一个扩展方法调用的示例,AsParallel()使性能加倍.这是横向扩展优于微优化的一个很好的例子,甚至不需要非常仔细地测量.注意我并不是说不需要微观优化,但是使用我们在这种抽象水平上可用的工具,需求变得非常小.
class Program
{
private const int ElementCount = 10000000;
static void Main(string[] args)
{
var str = generateString();
var stopwatch = new Stopwatch();
var list1 = new List<int>(ElementCount);
var list2 = new List<int>(ElementCount);
var split = str.Split(';');
stopwatch.Start();
list1.AddRange(split
.Select(ToInt32OrNull)
.Where(i => i != null)
.Cast<int>());
stopwatch.Stop();
TimeSpan nonParallel = stopwatch.Elapsed;
stopwatch.Restart();
list2.AddRange(split
.AsParallel()
.Select(ToInt32OrNull)
.Where(i => i != null)
.Cast<int>());
stopwatch.Stop();
TimeSpan parallel = stopwatch.Elapsed;
Debug.WriteLine("Non-parallel: {0}", nonParallel);
Debug.WriteLine("Parallel: {0}", parallel);
}
private static String generateString()
{
var builder = new StringBuilder(1048576);
var rnd = new Random();
for (int i = 0; i < ElementCount; i++)
{
builder.Append(rnd.Next(99999));
builder.Append(';');
}
builder.Length--;
return builder.ToString();
}
static int? ToInt32OrNull(string s)
{
int value;
return (Int32.TryParse(s, out value)) ? value : default(int?);
}
}
Run Code Online (Sandbox Code Playgroud)
非平行:00:00:07.0719911
平行:00:00:04.5933906
string str = "123;3344;4334;12";
List<int> list = new List<int>();
foreach (string s in str.Split(';'))
{
list.Add( Int32.Parse(s));
}
Run Code Online (Sandbox Code Playgroud)