如何使用C#基于CSV文件中的列查找并列出重复行。匹配/分组行。

问题描述 投票:0回答:3

我将excel文件转换为CSV文件。该文件包含超过100k条记录。我想通过搜索全名列来搜索并返回重复的行。如果全名匹配,我希望程序返回重复的整行。我开始使用一个代码来返回一个全名列表,但这是关于它的。

我已经列出了下面的代码:

public static void readCells()
    {
        var dictionary = new Dictionary<string, int>();

        Console.WriteLine("started");
        var counter = 1;
        var readText = File.ReadAllLines(path);
        var duplicatedValues = dictionary.GroupBy(fullName => fullName.Value).Where(fullName => fullName.Count() > 1);

        foreach (var s in readText)
        {
            var values = s.Split(new Char[] { ',' });
            var fullName = values[3];
            if (!dictionary.ContainsKey(fullName))
            {
                dictionary.Add(fullName, 1);
            }
            else
            {
                dictionary[fullName] += 1;

            }
            Console.WriteLine("Full Name Is: " + values[3]);

            counter++;
        }

    }
}
c# excel csv
3个回答
1
投票

我更改了字典以使用fullname作为键:

       public static void readCells()
        {
            var dictionary = new Dictionary<string, List<List<string>>>();

            Console.WriteLine("started");
            var counter = 1;
            var readText = File.ReadAllLines(path);
            var duplicatedValues = dictionary.GroupBy(fullName => fullName.Value).Where(fullName => fullName.Count() > 1);

            foreach (var s in readText)
            {
                List<string> values = s.Split(new Char[] { ',' }).ToList();
                string fullName = values[3];
                if (!dictionary.ContainsKey(fullName))
                {
                    List<List<string>> newList = new List<List<string>>();
                    newList.Add(values);
                    dictionary.Add(fullName, newList);
                }
                else
                {
                    dictionary[fullName].Add(values);

                }
                Console.WriteLine("Full Name Is: " + values[3]);

                counter++;
            }

        }

1
投票

我发现使用Microsoft内置的TextFieldParser(你可以在c#中使用,尽管它位于Microsoft.VisualBasic.FileIO命名空间中)可以简化CSV文件的读取和解析。

使用此类型,您的方法ReadCells()可以修改为以下扩展方法:

using Microsoft.VisualBasic.FileIO;

public static class TextFieldParserExtensions
{
    public static List<IGrouping<string, string[]>> ReadCellsWithDuplicatedCellValues(string path, int keyCellIndex, int nRowsToSkip /* = 0 */)
    {
        using (var stream = File.OpenRead(path))
        using (var parser = new TextFieldParser(stream))
        {
            parser.SetDelimiters(new string[] { "," });
            var values = parser.ReadAllFields()
                // If your CSV file contains header row(s) you can skip them by passing a value for nRowsToSkip
                .Skip(nRowsToSkip) 
                .GroupBy(row => row.ElementAtOrDefault(keyCellIndex))
                .Where(g => g.Count() > 1)
                .ToList();
            return values;
        }
    }

    public static IEnumerable<string[]> ReadAllFields(this TextFieldParser parser)
    {
        if (parser == null)
            throw new ArgumentNullException();
        while (!parser.EndOfData)
            yield return parser.ReadFields();
    }
}

您可以这样称呼:

var groups = TextFieldParserExtensions.ReadCellsWithDuplicatedCellValues(path, 3);

笔记:

  • TextFieldParser正确处理带有逃逸的嵌入式逗号的单元格,s.Split(new Char[] { ',' })不会这样做。
  • 由于您的CSV文件有超过100k的记录,我采用了流媒体策略来避免中间string[] readText内存分配。

0
投票

您可以尝试Cinchoo ETL - 一个开源库来解析CSV文件,并用几行代码识别重复项。

下面的示例CSV文件(EmpDuplicates.csv)

Id,Name
1,Tom
2,Mark
3,Lou
3,Lou
4,Austin
4,Austin
4,Austin

以下是解析和识别重复记录的方法

using (var parser = new ChoCSVReader("EmpDuplicates.csv").WithFirstLineHeader())
{
    foreach (dynamic c in parser.GroupBy(r => r.Id).Where(g => g.Count() > 1).Select(g => g.FirstOrDefault()))
        Console.WriteLine(c.DumpAsJson());
}

输出:

{
  "Id": 3,
  "Name": "Lou"
}
{
  "Id": 4,
  "Name": "Austin"
}

希望这可以帮助。

有关此库的更多详细用法,请访问https://www.codeproject.com/Articles/1145337/Cinchoo-ETL-CSV-Reader上的CodeProject文章

© www.soinside.com 2019 - 2024. All rights reserved.