我想写一个简单的程序来缓解我的工作生活,但我对 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/