繁体   English   中英

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

[英]Split multiple csv files by value from one csv file with c#

我需要打开一个csv文件。 比我需要过滤每个数据并为它们的每个值生成一个输出。

◘例子

•输入文件=“ full list.csv”

NAME        CITY
Mark        Venezia
John        New York
Lisa        San Miguel
Emily       New York
Amelia      New York
Nicolas     Venezia
Bill        San Miguel
Steve       Venezia

输出将是=

•file1 =“完整list_Venezia.csv”

NAME        CITY
Mark        Venezia
Nicolas     Venezia
Steve       Venezia

•file2 =“完整list_New York.csv”

NAME        CITY
John        New York
Emily       New York
Amelia      New York

•file3 =“完整列表_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()});
}

我假设您的DatiOutput看起来像以下,因为没有给出。

public class DatiOutput 
{
public string City{get;set;}
public string Name{get;set;}
}

然后,下一步是根据城市对集合进行分组,然后将其写入文件。 您可以使用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这使您可以根据特定条件(在本例中为City)将已读入的数据分组。

分组依据是功能强大的LINQ扩展,可让您过滤数据。 上面的示例读取所有数据,跳过标题,使用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

这是一种非LINQy的方法,该方法使用Dictionary来以城市名称作为Key来保持对每个输出文件的引用(但是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();
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM