【问题标题】:C# - check which element in a csv is not in an other csv and then write the elements to another csvC# - 检查 csv 中的哪个元素不在另一个 csv 中,然后将元素写入另一个 csv
【发布时间】:2021-12-01 11:27:45
【问题描述】:

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

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

【问题讨论】:

  • List<T>.IndexOf 是你的朋友。
  • @500-InternalServerError heck no.. HashSet 和/或 Dictionary
  • 那么这里有什么问题呢?你试过什么代码,你在哪里遇到问题。我们只能像您一样猜测,您的代码尝试将为我们澄清您的问题并提供上下文,以便我们能够以对您有用的方式做出响应。最终,您需要在 second CSV 中记录所有唯一国家/地区,数组或列表都可以,我们不是在谈论数千个条目。然后,您可以在 first CSV 中使用阅读器,只记录第二个中不存在的行(或国家/地区)。
  • 在您的代码示例中,我们有兴趣了解您是如何解析 csv 的,您是从第一个主体使用阅读器还是字符串拆分执行此操作,您是否使用像 CsvHelper 这样的库?
  • 请提供足够的代码,以便其他人更好地理解或重现问题。

标签: c# list csv tolist


【解决方案1】:

有很多方法可以实现这一点,对于许多现实世界的 CSV 应用程序,将 CSV 输入读取到类型化的内存存储中会很有帮助,有一些标准库可以帮助解决这个问题,如 CsvHelper发帖:Parsing CSV files in C#, with header

但是对于这个简单的要求,我们只需要从 master 列表中解析 Country 的值,在本例中为 second csv。我们不需要管理、验证或解析 CSV 中的任何其他字段

  1. 第二个 csv 构建唯一国家值列表
  2. 迭代第一个csv
    1. 获取Country
    2. 检查 第二个 csv 中的国家/地区列表
    3. 如果找不到国家,则写入第三个​​ 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);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-22
    • 2018-07-18
    • 1970-01-01
    相关资源
    最近更新 更多