之前已经问过这个问题,但这个具体部分还没有。 我有两个csv文件,1.csv和2.csv。
我首先将它们都转换为DataTable 它们都具有相同的模式:
1.csv
ID SUBID QTY Value
a 1 55 TEN
a 2 5 FIFTH
b 1 2 TE
我需要将上表与下表中映射的主键{ID,SUBID}与容差为1位数的QTY进行比较:
2.csv
ID SUBID QTY Value
a 1 5 TEN
a 2 6 FIFTH
b 1 2 TEN
输出应该只是2.csv值的差异数据和输出
output.csv
ID SUBID QTY Value
a 1 5
b 1 TEN
当然,这可以通过阅读1.csv中的所有值并使用{ID,SUBID} - >字典来完成。 {QTY,Value}并以这种方式匹配,但这是一个巨大的列表,时间复杂性将是巨大的。 我想知道是否有办法通过LiNQ执行此操作,即获取1.csv {ID,SUBID}与2.csv {ID,SUBID}匹配并遍历数据表,如果{QTY - 容差超过1的任何不匹配#OR str(Value)差异}把它放在一个新的数据表中。
答案 0 :(得分:2)
我会使用FileHelpers将您的csv加载到自定义类中,然后您可以执行此操作:
var inner=csv1.Join(csv2,
c1=>new {c1.ID,c1.SUBID},
c2=>new {c2.ID,c2.SUBID},
(c1,c2)=>new {c1,c2}).Where(c=>c.c1.Value!=c.c2.Value || Math.Abs(c1.QTY-c2.QTY)>1)
.Select(c=>new {
c2.ID,
c2.SUBID,
QTY=(c.c1.QTY==c.c2.Value)?null,c.c2.Value,
Value=c.c1.Value==c.c2.Value?null,c.c2.Value);
使用MoreLinq,您可以这样做:
var left=csv1.ExceptBy(csv2,c=>new {c.ID,c.SUBID})
.Select(c=>new {c.ID,c.SUBID,QTY=null,Value=null});
var right=csv2.ExceptBy(csv1,c=>new {c.ID,c.SUBID});
var combined=inner.Concat(left).Concat(right);
然后使用FileHelper将合并后的结果写回CSV。
如果您知道csv1中ID,SUBID的所有组合都在csv2中,并且csv2中的所有组合也在csv1中,那么您不需要左/右,只能输出内在的是什么。