我将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++;
}
}
}
我更改了字典以使用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++;
}
}
我发现使用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[] { ',' })
不会这样做。string[] readText
内存分配。您可以尝试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文章