c# -检查csv中的哪些元素不在其他csv中,然后将这些元素写入另一个csv



我的任务是检查一个csv中的列的哪些元素不包含在另一个csv中的列的元素中。在两个csv中都有一个国家列,任务是检查哪些国家不在第二个csv中,但在第一个csv中。

我想我必须解决它与列表后,我从两个csv读取字符串。但是我不知道如何检查第一个列表中的哪些项目不在另一个列表中,然后将其放到第三个列表中。

有很多方法可以实现这一点,对于许多现实世界的CSV应用程序来说,将CSV输入读入一个类型的内存存储是很有帮助的,有一些标准库可以帮助实现这一点,比如CsvHelper,正如这篇规范文章中解释的那样:然而,对于这个简单的需求,我们只需要从列表中解析Country的值,在本例中是第二个csv。我们不需要管理、验证或解析csv中的任何其他字段

  1. 第二个csv
  2. 创建一个唯一的国家值列表
  3. 迭代第一个csv
    1. 获取Country
    2. 对照第二个csv
    3. 中的国家列表进行核对
    4. 如果没有找到国家,则写入第三个csv

您可以在。net Fiddle

上测试以下代码

注意:这段代码使用StringWriterStringReader作为它们的接口是一样的读者和作家System.IO命名空间的文件。但是我们可以为这个简单的需求

消除与文件访问相关的复杂性
string inputcsv = @"Id,Field1,Field2,Country,Field3
1,one,two,Australia,three
2,one,two,New Zealand,three
3,one,two,Indonesia,three
4,one,two,China,three
5,one,two,Japan,three";
string masterCsv = @"Field1,Country,Field2
one,Indonesia,...
one,China,...
one,Japan,...";
string errorCsv = "";
// For all in inputCsv where the country value is not listed in the masterCsv
// Write to errorCsv

// Step 1: Build a list of unique Country values
bool csvHasHeader = true;
int countryIndexInMaster = 1;
char delimiter = ',';
List<string> countries = new List<string>();
using (var masterReader = new System.IO.StringReader(masterCsv))
{
string line = null;
if (csvHasHeader)
{
line = masterReader.ReadLine();
// an example of how to find the column index from first principals
if(line != null)
countryIndexInMaster = line.Split(delimiter).ToList().FindIndex(x => x.Trim('"').Equals("Country", StringComparison.OrdinalIgnoreCase));
}
while ((line = masterReader.ReadLine()) != null)
{
string country = line.Split(delimiter)[countryIndexInMaster].Trim('"');
if (!countries.Contains(country))
countries.Add(country);
}
}
// Read the input CSV, if the country is not in the master list "countries", write it to the errorCsv
int countryIndexInInput = 3;
csvHasHeader = true;
var outputStringBuilder = new System.Text.StringBuilder();
using (var outputWriter = new System.IO.StringWriter(outputStringBuilder))
using (var inputReader = new System.IO.StringReader(inputcsv))
{
string line = null;
if (csvHasHeader)
{
line = inputReader.ReadLine();
if (line != null)
{
countryIndexInInput = line.Split(delimiter).ToList().FindIndex(x => x.Trim('"').Equals("Country", StringComparison.OrdinalIgnoreCase));
outputWriter.WriteLine(line);
}
}
while ((line = inputReader.ReadLine()) != null)
{
string country = line.Split(delimiter)[countryIndexInInput].Trim('"');
if(!countries.Contains(country))
{
outputWriter.WriteLine(line);
}
}
outputWriter.Flush();
errorCsv = outputWriter.ToString();
}
// dump output to the console
Console.WriteLine(errorCsv);

既然您写的是用列表解决它,我假设您可以将这些值从CSV加载到列表中,那么让我们从:

开始:
List<string> countriesIn1st = LoadDataFrom1stCsv();
List<string> countriesIn2nd = LoadDataFrom2ndCsv();

那么你可以很容易地用linq:

解决它
List<string> countriesNotIn2nd = countriesIn1st.Where(country => !countriesIn2nd.Contains(country)).ToList();

现在你有了第三个列表,其中的国家在第一,但不在第二列表中。你可以保存它。