C# CSV Filehelpers 比较同一文件中的两行,添加和删除行

标签 c# csv datetime filehelpers

我想写一个简单的程序来缓解我的工作生活,但我对 C# 不太熟悉,所以我尝试阅读文档和一些示例,但我觉得文档不太好,并且找不到任何例子。

我有一个 CSV 文件(有时会失去连接或快速连续发送多个读数的无线温度传感器),我想比较两个后续行中的两个 DateTimes (TimeSpan),并根据结果删除该行,或添加另一个在这些之间。如果 2 个日期时间之间的时间跨度小于 10 分钟,则删除该行。如果超过 10 分钟,则创建一个新行,时间比第一行晚 10 分钟。所有读数均以 10 分钟的倍数为单位。

示例文件:

[DelimitedRecord(","), IgnoreFirst(1)]
public class CSVDataFields{
  [FieldQuoted('"')] [FieldConverter(ConverterKind.Date, "MM/dd/yyyy h:mm tt")]
  public DateTime Date;
  [FieldQuoted('"')]
  public float Value;
}

"Date","Value"
"03/19/2019 3:10 PM","20.5"
"03/19/2019 3:10 PM","20.5"
"03/19/2019 3:10 PM","20.4"
"03/19/2019 3:20 PM","20.2"
"03/19/2019 3:50 PM","20.0"
"03/19/2019 4:00 PM","19.8"

所以第一个检查是[0]和[1],小于10,所以删除那一行,[0]和[2]小于10-删除,[0]和[3]没问题,

[3] 和 [4] 超过 10 分钟,创建一个新行,时间为 ([3] + 10),平均值为 (20.2, 20.0),

new [4] and [5] 超过 10 分钟,用时间 ([4] + 10) 和平均值 (20.1, 20.0) 等创建一个新行。

在 FileHelpers.net 上的例子中只有这个例子。我想在这里您一次只能访问 1 行,而我需要同时访问 2 行。

private void DetectDupes(ref CSVDataFields[] csv){
  foreach(CSVDataFields csvData in csv){

  }
}

关于如何保存包含修改后的行的新文件,我还没有深入了解。

最佳答案

您可以使用 Linq 的 Aggregate 来完成此操作方法:

var engine = new FileHelperEngine<CSVDataFields>();

var result = engine.ReadFile(@"c:\temp\some_source_file.txt");

List<CSVDataFields> newRows = new List<CSVDataFields>();
newRows.Add(result.First());

result.Aggregate((a, b) =>
{
    var diff = Math.Abs((a.Date - b.Date).Minutes);
    if (diff < 10)
    {
        return a;
    }
    else if (diff == 10)
    {
        newRows.Add(b);
        return b;
    }
    else
    {
        var newRow = new CSVDataFields()
        {
            Date = a.Date.AddMinutes(10),
            Value = (a.Value + b.Value) / 2
        };
        newRows.Add(newRow);
        return newRow;
    }
});

engine.WriteFile(@"C:\temp\destination_file_deduped.txt", newRows);

输出:

03/19/2019 3:10 PM, 20.5

03/19/2019 3:20 PM, 20.2

03/19/2019 3:30 PM, 20.1

03/19/2019 3:40 PM, 19.95

解释: Aggregate方法遍历可枚举,执行一个函数委托(delegate),该函数委托(delegate)将可枚举中的每个项目的当前值(a)和下一个值(b)作为参数。在每次迭代中,它决定是否应该跳过新项目 b ( diff < 10 ),将其添加到去重列表 ( diff==10 ) 或合并 ( diff > 10 )。这里要理解的关键是 b始终是可枚举中的下一项,并且从当前迭代返回的值成为下一次迭代的当前值 ( a )。换句话说,a表示函数每次迭代的执行结果。

覆盖源文件通常不是一个好主意(除非您将其备份在某个地方),因此我正在输出到一个新文件,但如果需要,您可以更改它。

此外,这是一个简单的示例。确保考虑到诸如文件没有行之类的情况。

关于C# CSV Filehelpers 比较同一文件中的两行,添加和删除行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56365648/

相关文章:

python - 尝试获取 .csv 文件的一列中的最大数字

python - 从 Pandas 数据框中获取最小和最大日期

c# - 如何创建一个Windows App(C#),在其中可以在消息框中显示各种对象中的所有异常

c# - 可以使用 LINQ 从字符串中提取关键字吗?

python - 在加载到 pandas 数据框之前过滤掉 CSV 中的行

c# - Newtonsoft Json.NET ReferenceLoopHandling 和 JavascriptDateTimeConverter

javascript - 在 JavaScript 中检查日期是否在给定年份的 1 月 1 日之前

c# - 从 .NET 中的数据库中提取 varbinary 会导致 IndexOutOfRangeException

C# Excel 互操作 - 从 Range 中删除第一行

linux - 如何拆分 CSV 文件以保留第一列?