Parse CSV string into Array of Integers
我有一个文本框字段输入123145125i,将这个字段分隔成一个整数数组。如果一切分析正确,则验证此字段为真或假。
代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | private bool chkID(out int[] val) { char[] delimiters = new char[] { ',' }; string[] strSplit = iconeID.Text.Split(delimiters); int[] intArr = null; foreach (string s in strSplit) //splits the new parsed characters { int tmp; tmp = 0; if (Int32.TryParse(s, out tmp)) { if (intArr == null) { intArr = new int[1]; } else { Array.Resize(ref intArr, intArr.Length + 1); } intArr[intArr.Length - 1] = tmp; } if (Int32.TryParse(iconeID.Text, out tmp)) { iconeID.BorderColor = Color.Empty; iconeID.BorderWidth = Unit.Empty; tmp = int.Parse(iconeID.Text); val = new int[1]; val[0] = tmp; return true; } } val = null; ID.BorderColor = Color.Red; ID.BorderWidth = 2; return false; } |
/新代码:private bool chkid(out int[]val)//checkid函数的bool satus{string[]split=srtid.text.split(新字符[1]','];list numbers=new list();解析;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | bool isOk = true; foreach( string n in split){ if(Int32.TryParse( n , out parsed)) numbers.Add(parsed); else isOk = false; } if (isOk){ strID.BorderColor=Color.Empty; strID.BorderWidth=Unit.Empty; return true; } else{ strID.BorderColor=Color.Red; strID.BorderWidth=2; return false; } return numbers.ToArray(); } |
给定的函数似乎做得太多。这里有一个回答你标题中的问题:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | //int[] x = SplitStringIntoInts("1,2,3, 4, 5"); static int[] SplitStringIntoInts(string list) { string[] split = list.Split(new char[1] { ',' }); List<int> numbers = new List<int>(); int parsed; foreach (string n in split) { if (int.TryParse(n, out parsed)) numbers.Add(parsed); } return numbers.ToArray(); } |
编辑(基于您对问题的评论)
您已经定义了这个函数需要做的三件事。现在您只需要为每个方法创建方法。下面是我对如何实现它们的猜测。
1 2 3 4 5 6 7 8 9 10 11 12 13 | int[] ValidateIDs(int[] allIDs) { List<int> validIDs = new List<int>(allIDs); //remove invalid IDs return validIDs.ToArray(); } void DownloadXmlData(int[] ids) { ... } |
现在您只需执行新功能:
1 2 3 4 5 6 7 | void CheckIconeID(string ids) { int[] allIDs = SplitStringIntoInts(ids); int[] validIDs = ValidateIDs(allIDs); DownloadXmlData(validIDs); } |
我真的想对@austin salonen的答案发表评论,但不太合适。对于所问的问题,这是一个很好的答案,但我希望在csv/int转换部分更广泛地展开讨论。
- 这是一个小问题,不值得争论,但我会考虑将
foreach 循环换成一个普通的for 循环。你可能会得到更简单的IL(读得更快)。请参阅(http://www.codeproject.com/kb/cs/foreach.aspx,http://msdn.microsoft.com/en-us/library/ms973839.aspx[用于字符串迭代版本1的循环])。 - 我将创建两种方法——一种是安全的,使用
TryParse ,只添加"好"值,另一种不是安全的,而是更快的。
建议的"安全"功能(如果不想知道错误的值,则使用重载)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | public static int[] SplitAsIntSafe (this string csvString) { List<string> badVals; return SplitAsIntSafe(csvString, ',', out badVals); } public static int[] SplitAsIntSafe (this string delimitedString, char splitChar, out List<string> badVals) { int parsed; string[] split = delimitedString.Split(new char[1] { ',' }); List<int> numbers = new List<int>(); badVals = new List<string>(); for (var i = 0; i < split.Length; i++) { if (int.TryParse(split[i], out parsed)) { numbers.Add(parsed); } else { badVals.Add(split[i]); } } return numbers.ToArray(); } |
提议的"快速"功能……
1 2 3 4 5 6 7 8 9 10 11 12 | public static int[] SplitAsIntFast (this string delimitedString, char splitChar) { string[] strArray = delimitedString.Split(splitChar); int[] intArray = new int[strArray.Length]; if(delimitedString == null) { return new int[0]; } for (var i = 0; i < strArray.Length; i++) { intArray[i] = int.Parse(strArray[i]); } return intArray; } |
无论如何,希望这能帮助别人。
有一个很好的用于分析csv文件的免费库:filehelpers
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | using FileHelpers; // First declare the record class [Delimitedrecord(";")] public class SampleType { public string Field1; public int Field2; } public void ReadExample() { FileHelperEngine engine = new FileHelperEngine(typeof(SampleType)); SampleType[] records; records = (SampleType[]) engine.ReadFile("source.txt"); // Now"records" array contains all the records in the // sourcefile and can be acceded like this: int sum = records[0].Field2 + records[1].Field2; } |
检查这个文件帮助器和csv阅读器可能是值得的。
希望他们能帮助你…当心,汤姆
在.NET 2.0中,您可以编写
1 2 3 4 5 6 7 8 9 10 11 12 13 | string test ="123,14.5,125,151,1.55,477,777,888"; bool isParsingOk = true; int[] results = Array.ConvertAll<string,int>(test.Split(','), new Converter<string,int>( delegate(string num) { int r; isParsingOk &= int.TryParse(num, out r); return r; })); |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | public bool ParseAndCheck(string source, out IList<int> goodItems, out IList<string> badItems) { goodItems = new List<int>(); badItems = new List<string>(); foreach (string item in source.Split(',')) { int temp; if (int.TryParse(item, out temp)) goodItems.Add(temp); else badItems.Add(item); } return (badItems.Count < 1); } |
这很简单,我认为效果很好。它只返回有效数字:
1 2 3 4 5 6 7 | static int[] SplitStringIntoInts(string list) { int dummy; return (from x in list.Split(',') where int.TryParse(x.ToString(), out dummy) select int.Parse(x.ToString())).ToArray(); } |