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

前端 未结 4 1478
谎友^
谎友^ 2020-12-17 04:40

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).S         


        
相关标签:
4条回答
  • 2020-12-17 05:18

    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. That can be parsed to an int. If you remove the Skip(2) you are trying to parse all of them. 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(','); and 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. It doesn't fix anything. It would also work with int.Parse.

    Update: as has been proved by Eric Lippert in the comment section using int.TryParse in a LINQ query can be harmful. So it's better to use a helper method that encapsulates int.TryParse and returns a 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:

    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();
    
    0 讨论(0)
  • 2020-12-17 05:21

    you might try

        string line = "[1,2,3]";
        IEnumerable<int> intValues = from i in line.Split(',')
                                     select Convert.ToInt32(i.Trim('[', ' ', ']'));
    
    0 讨论(0)
  • 2020-12-17 05:29

    I think it would be better you do it this way:

    JsonConvert.DeserializeObject(line, typeof(List<int>));
    
    0 讨论(0)
  • 2020-12-17 05:41

    The reason it does not work unless you skip the first two lines is that these lines have commas after ints. Your input looks like this:

    "1," "2," "3"
    

    Only the last entry can be parsed as an int; the initial two will produce an exception.

    Passing comma and space as separators to Split will fix the problem:

    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.

    0 讨论(0)
提交回复
热议问题