简体   繁体   English

C#LINQ:字符串(“[1,2,3]”)如何解析为数组?

[英]C# LINQ: How is string(“[1, 2, 3]”) parsed as an array?

I am trying to parse a string into array and find a very concise approach. 我试图将一个字符串解析成数组,并找到一个非常简洁的方法。

string line = "[1, 2, 3]";
string[] input = line.Substring(1, line.Length - 2).Split();
int[] num = input.Skip(2)
                 .Select(y => int.Parse(y))
                 .ToArray();

I tried remove Skip(2) and I cannot get the array because of non-int string. 我尝试删除Skip(2),因为非int字符串,我无法获取数组。 My question is that what is the execution order of those LINQ function. 我的问题是那些LINQ函数的执行顺序是什么。 How many times is Skip called here? Skip在这里打了多少次?

Thanks in advance. 提前致谢。

The order is the order that you specify. 订单是您指定的订单。 So input.Skip(2) skips the first two strings in the array, so only the last remains which is 3 . 所以input.Skip(2)跳过数组中的前两个字符串,所以只有最后一个字符串是3 That can be parsed to an int . 这可以解析为int If you remove the Skip(2) you are trying to parse all of them. 如果你删除Skip(2)你试图解析所有这些。 That doesn't work because the commas are still there. 这不起作用,因为逗号仍在那里。 You have splitted by white-spaces but not removed the commas. 您已使用空格分割,但未删除逗号。

You could use line.Trim('[', ']').Split(','); 你可以使用line.Trim('[', ']').Split(','); and int.TryParse : int.TryParse

string line = "[1, 2, 3]";
string[] input = line.Trim('[', ']').Split(',');
int i = 0;
int[] num = input.Where(s => int.TryParse(s, out i)) // you could use s.Trim but the spaces don't hurt
                 .Select(s => i)
                 .ToArray(); 

Just to clarify, i have used int.TryParse only to make sure that you don't get an exception if the input contains invalid data. 只是为了澄清,我使用int.TryParse只是为了确保在输入包含无效数据时不会出现异常。 It doesn't fix anything. 它没有任何修复。 It would also work with int.Parse . 它也适用于int.Parse

Update : as has been proved by Eric Lippert in the comment section using int.TryParse in a LINQ query can be harmful. 更新 :正如Eric Lippert 在评论部分中使用int.TryParse在LINQ查询中证明的那样可能是有害的。 So it's better to use a helper method that encapsulates int.TryParse and returns a Nullable<int> . 因此最好使用封装int.TryParse的helper方法并返回Nullable<int> So an extension like this: 所以像这样的扩展:

public static int? TryGetInt32(this string item)
{
    int i;
    bool success = int.TryParse(item, out i);
    return success ? (int?)i : (int?)null;
}

Now you can use it in a LINQ query in this way: 现在,您可以通过以下方式在LINQ查询中使用它:

string line = "[1, 2, 3]";
string[] input = line.Trim('[', ']').Split(',');
int[] num = input.Select(s => s.TryGetInt32())
                 .Where(n => n.HasValue)
                 .Select(n=> n.Value)
                 .ToArray();

The reason it does not work unless you skip the first two lines is that these lines have commas after int s. 除非你跳过前两行,否则它不起作用的原因是这些行在int之后有逗号。 Your input looks like this: 您的输入如下所示:

"1," "2," "3"

Only the last entry can be parsed as an int ; 只有最后一个条目可以解析为int ; the initial two will produce an exception. 最初的两个会产生异常。

Passing comma and space as separators to Split will fix the problem: 将逗号和空格作为分隔符传递给Split将解决问题:

string[] input = line
    .Substring(1, line.Length - 2)
    .Split(new[] {',', ' '}, StringSplitOptions.RemoveEmptyEntries);

Note the use of StringSplitOptions.RemoveEmptyEntries to remove empty strings caused by both comma and space being used between entries. 请注意使用StringSplitOptions.RemoveEmptyEntries删除由条目之间使用的逗号和空格引起的空字符串。

我觉得你这样做会更好:

JsonConvert.DeserializeObject(line, typeof(List<int>));

you might try 你可能会试试

    string line = "[1,2,3]";
    IEnumerable<int> intValues = from i in line.Split(',')
                                 select Convert.ToInt32(i.Trim('[', ' ', ']'));

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM