繁体   English   中英

Int.Parse(String.Split())返回“输入字符串格式不正确”错误

[英]Int.Parse(String.Split()) returns “Input string was not in a correct format” error

我正在尝试对数组执行LINQ查询,以根据用户查询过滤出结果。 我在从单个字符串解析两个int时遇到问题。

在我的数据库中,时间级别以字符串形式存储,格式为[mintime]-[maxtime] minutes ,例如0-5 Minutes 我的用户有一个滑块,他们可以选择一个最小和最大时间范围,并将其存储为一个带有两个值的int数组。 我试图将[mintime]与第一个值进行比较,并将[maxtime]与第二个值进行比较,以找到适合用户时间范围的数据库条目。

这是我应该执行该过滤的来自控制器的C#代码:

RefinedResults = InitialResults.Where(
                x => int.Parse(x.TimeLevel.Split('-')[0]) >= data.TimeRange[0] &&
                int.Parse(x.TimeLevel.Split('-')[1]) <= data.TimeRange[1] &&).ToArray();

我的想法是,它将首先在-处分割0-5 Minutes字符串,从而产生两个字符串05 Minutes ,然后从中解析出整数,从而得到05

但是一旦到达Int.Parse,它就会在标题中引发错误。

一些x.TimeLevel数据库记录存储为"30-40+ Minutes" 有什么方法可以提取int吗?

您可以使用正则表达式为您匹配字符串的整数部分,如下所示:

RefinedResults = InitialResults
    .Where(x => {
        var m = Regex.Match(x, @"^(\d+)-(\d+)");
        return m.Success
            && int.Parse(m.Groups[1]) >= data.TimeRange[0]
            && int.Parse(m.Groups[2]) <= data.TimeRange[1];
    }).ToArray();

此方法要求字符串以一对以短划线分隔的十进制数字开头。 它会忽略第二个数字之后的所有内容,从而确保仅将数字序列传递给int.Parse

您的代码无法正常工作的原因是string.Split(“-”,“ 0-5 Minutes”)将返回[0] =“ 0”和[1] =“ 5 Minutes”,而后者是不可解析的作为一个整数。

您可以使用正则表达式“ \\ d +”分割数字组并忽略非数字。 这应该工作:

var refinedResults = 
(
    from result in InitialResults
    let numbers = Regex.Matches(result.TimeLevel, @"\d+")
    where ((int.Parse(numbers[0].Value) >= data.TimeRange[0]) && (int.Parse(numbers[1].Value) <= data.TimeRange[1]))
    select result
).ToArray();

这是一个完整的可编译控制台应用程序,演示了它的工作原理。 我用虚拟类来代表您的实际类。

using System;
using System.Linq;
using System.Text.RegularExpressions;

namespace ConsoleApplication2
{
    public class SampleTime
    {
        public SampleTime(string timeLevel)
        {
            TimeLevel = timeLevel;
        }

        public readonly string TimeLevel;
    }

    public class Data
    {
        public int[] TimeRange = new int[2];
    }

    class Program
    {
        private static void Main(string[] args)
        {
            var initialResults = new []
            {
                new SampleTime("0-5 Minutes"),
                new SampleTime("4-5 Minutes"), // Should be selected below.
                new SampleTime("1-8 Minutes"),
                new SampleTime("4-6 Minutes"), // Should be selected below.
                new SampleTime("4-7 Minutes"),
                new SampleTime("5-6 Minutes"), // Should be selected below.
                new SampleTime("20-30 Minutes")
            };

            // Find all ranges between 4 and 6 inclusive.

            Data data = new Data();
            data.TimeRange[0] = 4;
            data.TimeRange[1] = 6;

            // The output of this should be (as commented in the array initialisation above):
            //
            // 4-5 Minutes
            // 4-6 Minutes
            // 5-6 Minutes

            // Here's the significant code:

            var refinedResults = 
            (
                from result in initialResults
                let numbers = Regex.Matches(result.TimeLevel, @"\d+")
                where ((int.Parse(numbers[0].Value) >= data.TimeRange[0]) && (int.Parse(numbers[1].Value) <= data.TimeRange[1]))
                select result
            ).ToArray();

            foreach (var result in refinedResults)
            {
                Console.WriteLine(result.TimeLevel);
            }
        }
    }
}

问题是您正在按-而不是作为minutes部分分隔符的空格进行拆分。 因此,您可以改用Split(' ', '-')

InitialResults
    .Where(x => int.Parse(x.TimeLevel.Split('-')[0]) >= data.TimeRange[0] 
             && int.Parse(x.TimeLevel.Split(' ','-')[1]) <= data.TimeRange[1])
    .ToArray();

顺便说一句,不要在数据库的一列中存储三个信息。 那只是令人讨厌的错误和不良性能的根源。 在数据库中进行筛选(这是首选方法)或维护数据库一致性也更加困难。


关于您的评论,格式可以是0-40+ Minutes 那你可以用...

InitialResults
    .Select(x => new { 
        TimeLevel = x.TimeLevel, 
        MinMaxPart = x.TimeLevel.Split(' ')[0]
    })
    .Select(x => new { 
        TimeLevel = x.TimeLevel, 
        Min = int.Parse(x.MinMaxPart.Split('-')[0].Trim('+')),
        Max = int.Parse(x.MinMaxPart.Split('-')[1].Trim('+'))
    })
    .Where(x => x.Min >= data.TimeRange[0] && x.Max <= data.TimeRange[1])
    .Select(x => x.TimeLevel)
    .ToArray();

由于字符串的“分钟”部分而发生错误。 您可以在拆分之前截断“分钟”部分,例如; x.TimeLevel.Remove(x.IndexOf(“”))),则可以拆分。

暂无
暂无

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

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