[英]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
字符串,从而产生两个字符串0
和5 Minutes
,然后从中解析出整数,从而得到0
和5
。
但是一旦到达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.