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

时间:2017-12-15 15:57:13

标签: c# excel csv

我将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++;
        }

    }
}

3 个答案:

答案 0 :(得分:1)

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

 $("#fileupload").fileupload({
        url: "/upload/server/php/",
        dataType: "json",
        limitMultiFileUploadSize: 400971520,
        limitMultiFileUploadSizeOverhead: 400971520,
        maxFileSize: 400971520,
        disableImageResize: /Android(?!.*Chrome)|Opera/ .test(window.navigator.userAgent),
        acceptFileTypes: /(\.|\/)(pdf|jpe?g|png|bmp|tif?f)$/i,
        autoUpload: true,
});

答案 1 :(得分:1)

我发现使用Microsoft的内置TextFieldParser(尽管位于Microsoft.VisualBasic.FileIO命名空间中,您可以在c#中使用)可以简化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内存分配。

答案 2 :(得分: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文章