[英]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();
有沒有可以過濾所需數據的算法?
您已經自己編寫了大部分好的部分,現在您需要填補空白。 分解步驟
第一步當然是讀取輸入文件
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.