我正在尝试对数组执行LINQ查询,以根据用户的查询过滤掉结果。我在从单个字符串解析两个int
时遇到问题。
在我的数据库中,TimeLevels以[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,它就会在标题中抛出错误。
答案 0 :(得分:1)
某些
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
。
答案 1 :(得分:1)
你的代码不起作用的原因是因为string.Split(“ - ”,“0-5 Minutes”)将返回[0] =“0”和[1] =“5 Minutes”,后者不能作为int解析。
您可以使用正则表达式“\ 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);
}
}
}
}
答案 2 :(得分:0)
问题是你要按-
分割,而不是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();
答案 3 :(得分:0)
错误发生是因为&#34;分钟&#34;字符串的一部分。 你可以截断&#34;分钟&#34;分裂之前的部分,如; x.TimeLevel.Remove(x.IndexOf(&#34;&#34;)) 然后就可以拆分了。