爆炸lambda表达式

时间:2017-01-03 01:12:04

标签: c#

下面的代码对我有用,但是我想在添加到表之前添加一个条件。我需要的是 - 如果“扫描时间”在两个日期之间,那么它应该被添加到“表格”中,如果没有,那么它应该被忽略。

这是用于选择文件..

private void btnSelectFile_Click(object sender, EventArgs e)
{
    OpenFileDialog ofd = new OpenFileDialog()
    {
        Title = "Select the file to open.",
        Filter = "DAT (*.dat)|*.dat|TXT (*.txt)|*.txt|All Files (*.*)|*.*",
        InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments)
    };

    if (ofd.ShowDialog() == DialogResult.OK)
    {
        txtFilePath.Text = ofd.FileName;
        loadDataToGridview();
    }
}

这是用于读取文件,然后将其添加到datagridview

private void loadDataToGridview()
{
    DataTable table = new DataTable();
    table.Columns.Add("Emp ID");
    table.Columns.Add("Scan Time");
    table.Columns.Add("Undefined 1");
    table.Columns.Add("Undefined 2");
    table.Columns.Add("Undefined 3");
    table.Columns.Add("Undefined 4");

    var lines = File.ReadAllLines(txtFilePath.Text).ToList();
    lines.ForEach(line => table.Rows.Add(line.Split((char)9)));
    return table;
}

我从这里得到了loadDataToGridview方法,但我不知道如何爆炸

lines.ForEach(line => table.Rows.Add(line.Split((char)9)));

lambda表达式包含我需要的条件。我们假设datepickers的名称是dateFrom和dateTo。 非常感谢您的帮助。

3 个答案:

答案 0 :(得分:3)

不要使用ReadAllLines方法,因为它会将整个文件加载到内存中。换句话说,如果您的日期之间只有1行,为什么要加载整个文件。

请改用ReadLines方法。为什么?请参阅我的回答here

var lines = File.ReadLines("").Select(x => Split(x)).Where(x => IsBetweenDates(x[1]));
lines.ForEach(row => table.Rows.Add(row));
dataGridView1.DataSource = table;

您应该根据需要在此处添加自己的错误处理。我为你添加了一些:

private bool IsBetweenDates(string value)
{ 
    var dateValue = DateTime.ParseExact(value, "yyyy-MM-dd HH:mm:ss", CultureInfo.InvariantCulture);
    return dateValue >= fromDate.Value && dateValue <= toDate.Value;
}

private string[] Split(string line)
{
    if (string.IsNullOrWhitespace(x))
    {
        // There is nothing in this line. Is this allowed in your case?
        // If yes do whatever you need to do here. For example, log it or something.
    }
    var splits = line.Split((char)9);
    if (splits.Length != 6)
    {
        // This line does not have 6 fields so what do you want to do?
    }

    return splits;
}

答案 1 :(得分:0)

使用Where() as suggested by @CodingYoshi,但先使用Select()语句拆分该行(因此您不必两次):

var lines = File.ReadAllLines(txtFilePath.Text).Select(line => line.Split(';')).Where(fields => fields[1] >= fromDate && fields[1] <= toDate).ToList();
lines.ForEach(row => table.Rows.Add(row));

您可能还想考虑使用CsvHelper之类的内容而不是手动解析文件

答案 2 :(得分:0)

您也可以使用Select Method来获取与过滤条件匹配的所有DataRow对象的数组。

DataTable table = new DataTable();
table.Columns.Add("Emp ID");
//Add All your columns
var lines = File.ReadAllLines(txtFilePath.Text).ToList();
lines.ForEach(line => table.Rows.Add(line.Split((char)9)));
//Till the data has been already there in your DataTable. 
//Create a new DataTable for Filtered Records.
DataTable FilteredTable = new DataTable();
//The Statement works like a SQL Statement which is equal to
//Select * from TableName Where DateColumn Between two dates. 
DataRow[] rows = table.Select("date >= #" + from_date + "# AND date <= #" + to_date + "#");
//Now add all rows to the new Table.
foreach (DataRow dr in rows) 
{
    FilteredTable.ImportRow(dr);
}
dataGridView1.DataSource = FilteredTable;

如果from_dateto_date是DateTime而不是字符串,则需要使用ToString(您的日期格式)来获取正确的sql语句