我有一个像这样的CSV文件:
1,01/01/2001,hello
2,19/09/2013,world
3,12/05/2016,world
4,13/05/2016,hello
5,12/12/2012,world
6,05/02/2006,world
7,06/03/2011,hello
string parts = new StringReader(@"C:\input.txt").ReadToEnd();
string[] lines = parts.Split(new string[] { Environment.NewLine }, StringSplitOptions.None);
StringBuilder sb = new StringBuilder();
List<string> dates = new List<string>();
for (int i = 0; i < lines.Length; i++)
{
string[] data = lines[i].Split(new string[] { "," }, StringSplitOptions.None);
dates.Add(data[1]);
}
var datesSorted = dates.OrderBy(x => DateTime.ParseExact(x, "dd/MM/yyyy", null));
foreach (string s in datesSorted)
{
sb.AppendLine(s + "<br />");
}
Label1.Text = sb.ToString();
上面的代码工作正常,但现在我有另一个问题。我想在代码中添加一个if
语句,只显示所选值的日期,我能想到的就是这样做:
string parts = new StringReader(@"C:\input.txt").ReadToEnd();
string[] lines = parts.Split(new string[] { Environment.NewLine }, StringSplitOptions.None);
StringBuilder sb = new StringBuilder();
List<string> dates = new List<string>();
for (int i = 0; i < lines.Length; i++)
{
string[] data = lines[i].Split(new string[] { "," }, StringSplitOptions.None);
dates.Add(data[1]);
var datesSorted = dates.OrderBy(x => DateTime.ParseExact(x, "dd/MM/yyyy", null));
if (data[2] == "hello")
{
foreach (string s in datesSorted)
{
sb.AppendLine(s + "<br />");
}
Label1.Text = sb.ToString();
}
}
或者将if
语句放在foreach
循环中,这会产生相同的输出:
01/01/2001
01/01/2001
19/09/2013
12/05/2016
13/05/2016
01/01/2001
05/02/2006
06/03/2011
12/12/2012
19/09/2013
12/05/2016
13/05/2016
答案 0 :(得分:1)
在我看来,使用LINQ可以使代码更简单。
试试这个:
var lines = File.ReadAllLines(@"C:\input.txt");
var query =
from line in lines
let data = line.Split(',')
where data[2] == "hello"
orderby DateTime.ParseExact(data[1], "dd/MM/yyyy", null)
select data[1];
var dates = query.ToList();
Label1.Text = String.Join("", dates.Select(x => x + "<br />"));
这会使用if
中的where data[2] == "hello"
处理您想要的query
语句。
答案 1 :(得分:0)
您可能要考虑做的事情之一是使用中间类来表示csv行,例如
private class CSVEntry
{
public int EntryNo { get; set; }
public DateTime Date { get; set; }
public string Text { get; set; }
}
然后将数据加载更改为:
List<CSVEntry> csvlist = new List<CSVEntry>();
for (int i = 0; i < lines.Length; i++)
{
string[] data = lines[i].Split(new string[] { "," }, StringSplitOptions.None);
csvlist.Add(new CSVEntry() { EntryNo = Int32.Parse(data[0]), Date = DateTime.ParseExact(data[1], "dd/MM/yyyy", null), Text = data[2] });
}
然后通过执行以下操作选择要显示的内容:
var results = csvlist.Where(x => x.Text == "hello").OrderBy(x => x.Date);
Label1.Text = String.Join("<br />", results.Select(x => x.Date.ToString("dd/MM/yyyy"));
以这种方式执行此操作的好处是您可以重新使用之前加载的内容,并且可以在LINQ投影中完成显示新值的任何更改。
修改强>
我建议你将'loading'移到一个单独的函数中,例如
public List<CSVEntry> LoadData(string filename, ... other params) {...
然后是您要查找特定条目的部分
public IEnumerable<CSVEntry> FindByName(List<CSVEntry> loadedData, ICollection<string> targetNames)
{
return loadedData.Where(x => targetNames.Contains(x.Text));
}
继续,您可以通过将数组/列表传递给函数
来调用它var results = FindByName(csvList, new string[] { "hello", "world"});