在foreach循环中添加if语句的位置?

时间:2016-05-13 02:27:39

标签: c# asp.net .net

我有一个像这样的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

我昨天问过code这套question

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

2 个答案:

答案 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"});