C# 使用c从一个csv文件中按值拆分多个csv文件

C# 使用c从一个csv文件中按值拆分多个csv文件,c#,console-application,C#,Console Application,我需要打开一个csv文件。然后我需要过滤每个数据,并为其中的每个值生成一个输出 ◘ 范例 •输入文件=完整列表.csv NAME CITY Mark Venezia John New York Lisa San Miguel Emily New York Amelia New York Nicolas Venezia Bill San Miguel Steve Venezia 输出将

我需要打开一个csv文件。然后我需要过滤每个数据,并为其中的每个值生成一个输出

◘ 范例

•输入文件=完整列表.csv

NAME        CITY
Mark        Venezia
John        New York
Lisa        San Miguel
Emily       New York
Amelia      New York
Nicolas     Venezia
Bill        San Miguel
Steve       Venezia
输出将是=

•文件1=完整列表_Venezia.csv

NAME        CITY
Mark        Venezia
Nicolas     Venezia
Steve       Venezia
•文件2=完整列表\u New York.csv

NAME        CITY
John        New York
Emily       New York
Amelia      New York
•文件3=完整列表\u San Miguel

NAME        CITY
Lisa        San Miguel
Bill        San Miguel
我在Visual Studio上将c与ConsoleApplication一起使用,并开始使用以下方法读取输入文件:

string inputFile = "full list.csv";
string outputFile;
string line;
string titles = File.ReadLines(inputFile).First();
System.IO.StreamReader file = new System.IO.StreamReader(inputFile);
while ((line = file.ReadLine()) != null)
{
}
file.Close();

System.IO.StreamWriter fileOut = new System.IO.StreamWriter(outputFile);
foreach (DatiOutput objOut in listOutput)
{
}
fileOut.Close();

有没有一种算法可以让我过滤我需要的数据?

大部分好的部分都是你自己写的,现在你需要填补空白。 分解台阶

将CSV读取到集合中 基于城市的群集合 写下 每个组都需要单独的文件 第一步当然是读取输入文件

var listOutput = new List<DatiOutput>();
while ((line = file.ReadLine()) != null)
{
    var data = line.Split(new []{";"},StringSplitOptions.RemoveEmptyEntries);
    if(!data[0].Trim().Equals("NAME"))
        listOutput.Add(new DatiOutput{ Name = data[0].Trim(), City = data[1].Trim()});
}
然后下一步是根据城市对集合进行分组,然后将它们写入文件。可以使用LINQ根据城市对集合进行分组

listOutput.GroupBy(c=>c.City)
获得结果后,现在可以创建附加了相应城市名称的文件名,并向其中添加数据

foreach (var objOut in listOutput.GroupBy(c=>c.City))
{
    var filePath = $"{Path.Combine(Path.GetDirectoryName(inputFile),Path.GetFileNameWithoutExtension(inputFile))}_{objOut.First().City}.csv";

    using(System.IO.StreamWriter fileOut = new System.IO.StreamWriter(File.Open(filePath, FileMode.OpenOrCreate, FileAccess.ReadWrite)))
    {
        fileOut.WriteLine($"NAME;CITY");
        foreach(var items in objOut)
        {
            fileOut.WriteLine($"{items.Name};{items.City}");
        }
    }
}

你会得到想要的结果

你自己已经写了大部分好的部分,现在你需要填补空白。
foreach (var g in File.ReadAllLines("full list.csv")
    .Skip(1)
    .Select(l => new {
        Name = l.Substring(0, l.IndexOf(',')),
        City = l.Substring(l.IndexOf(',') + 1) })
    .GroupBy(l => l.City))
{
    File.WriteAllLines($"full list_{g.Key}.csv", new[] { "NAME,CITY" }
        .Concat(g.Select(l => $"{l.Name},{l.City}")));
}
分解台阶

将CSV读取到集合中 基于城市的群集合 写下 每个组都需要单独的文件 第一步当然是读取输入文件

var listOutput = new List<DatiOutput>();
while ((line = file.ReadLine()) != null)
{
    var data = line.Split(new []{";"},StringSplitOptions.RemoveEmptyEntries);
    if(!data[0].Trim().Equals("NAME"))
        listOutput.Add(new DatiOutput{ Name = data[0].Trim(), City = data[1].Trim()});
}
然后下一步是根据城市对集合进行分组,然后将它们写入文件。可以使用LINQ根据城市对集合进行分组

listOutput.GroupBy(c=>c.City)
获得结果后,现在可以创建附加了相应城市名称的文件名,并向其中添加数据

foreach (var objOut in listOutput.GroupBy(c=>c.City))
{
    var filePath = $"{Path.Combine(Path.GetDirectoryName(inputFile),Path.GetFileNameWithoutExtension(inputFile))}_{objOut.First().City}.csv";

    using(System.IO.StreamWriter fileOut = new System.IO.StreamWriter(File.Open(filePath, FileMode.OpenOrCreate, FileAccess.ReadWrite)))
    {
        fileOut.WriteLine($"NAME;CITY");
        foreach(var items in objOut)
        {
            fileOut.WriteLine($"{items.Name};{items.City}");
        }
    }
}
你会得到想要的结果

foreach (var g in File.ReadAllLines("full list.csv")
    .Skip(1)
    .Select(l => new {
        Name = l.Substring(0, l.IndexOf(',')),
        City = l.Substring(l.IndexOf(',') + 1) })
    .GroupBy(l => l.City))
{
    File.WriteAllLines($"full list_{g.Key}.csv", new[] { "NAME,CITY" }
        .Concat(g.Select(l => $"{l.Name},{l.City}")));
}
您的示例缺少的关键部分是GroupBy—这允许您根据案例城市中的特定标准将读入的数据分组

GroupBy是一个强大的扩展,允许您过滤数据。上面的示例读取所有数据,跳过标题,使用select将每一行转换为包含名称和城市的实例。然后使用GroupBy按城市对这些实例进行分组。然后,对于每个组,将数据写入一个新文件

您的示例缺少的关键部分是GroupBy—这允许您根据案例城市中的特定标准将读入的数据分组


GroupBy是一个强大的扩展,允许您过滤数据。上面的示例读取所有数据,跳过标题,使用select将每一行转换为包含名称和城市的实例。然后使用GroupBy按城市对这些实例进行分组。然后将每组数据写入一个新文件。

通过在整个解决方案上保持相同的代码样式,我将@TVOHMs的答案带到稍微清晰的方向

File.ReadAllLines("full list.csv")         // Read the input file
    .Skip(1)                               // Skip the header row
    .Select(row => row.Split(','))         // Split each row to array of city and name
    .GroupBy(row => row[1], row => row[0]) // Group by cities, selecting names
    .ToList()                              // To list, so .ForEach is possible
    .ForEach(group => File.WriteAllLines($"full list_{group.Key}.csv", group)); // Create file for each group and write the names

通过在整个解决方案上保持相同的代码样式,我将@TVOHMs的答案带到稍微清晰的方向

File.ReadAllLines("full list.csv")         // Read the input file
    .Skip(1)                               // Skip the header row
    .Select(row => row.Split(','))         // Split each row to array of city and name
    .GroupBy(row => row[1], row => row[0]) // Group by cities, selecting names
    .ToList()                              // To list, so .ForEach is possible
    .ForEach(group => File.WriteAllLines($"full list_{group.Key}.csv", group)); // Create file for each group and write the names

这里有一种非LINQy的方法,使用字典根据城市名称作为键保留对每个输出文件的引用LINQ没有什么问题

string[] values;
string header;
string line, city, outputFileName;
string inputFile = "full list.csv";
Dictionary<string, System.IO.StreamWriter> outputFiles = new Dictionary<string, System.IO.StreamWriter>();
using (System.IO.StreamReader file = new System.IO.StreamReader(inputFile))
{
    header = file.ReadLine();
    while ((line = file.ReadLine()) != null)
    {
        values = line.Split(",".ToCharArray());
        city = values[1];
        if (!outputFiles.ContainsKey(city))
        {
            outputFileName = "full list_" + city + ".csv";
            outputFiles.Add(city, new System.IO.StreamWriter(outputFileName));
            outputFiles[city].WriteLine(header);
        }
        outputFiles[city].WriteLine(line);
    }
}   
foreach(System.IO.StreamWriter outputFile in outputFiles.Values)
{
    outputFile.Close();
}

这里有一种非LINQy的方法,使用字典根据城市名称作为键保留对每个输出文件的引用LINQ没有什么问题

string[] values;
string header;
string line, city, outputFileName;
string inputFile = "full list.csv";
Dictionary<string, System.IO.StreamWriter> outputFiles = new Dictionary<string, System.IO.StreamWriter>();
using (System.IO.StreamReader file = new System.IO.StreamReader(inputFile))
{
    header = file.ReadLine();
    while ((line = file.ReadLine()) != null)
    {
        values = line.Split(",".ToCharArray());
        city = values[1];
        if (!outputFiles.ContainsKey(city))
        {
            outputFileName = "full list_" + city + ".csv";
            outputFiles.Add(city, new System.IO.StreamWriter(outputFileName));
            outputFiles[city].WriteLine(header);
        }
        outputFiles[city].WriteLine(line);
    }
}   
foreach(System.IO.StreamWriter outputFile in outputFiles.Values)
{
    outputFile.Close();
}

这些列是固定宽度的,还是制表符分隔的?输入文件中有分隔符逗号。我在描述中所说的是,当您使用Excel打开csv文件时,您会看到哪些是固定宽度的列,或者可能是以制表符分隔的列?在输入文件中有分隔符逗号。我在描述中所说的是,当你用excelit打开csv文件时,你会看到什么,但是第一行——带有标题名称和城市的那一行——不会写编辑作品,但是第一行——带有标题名称和城市的那一行——不会写