我需要打开一个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 =“完整列表_New York.csv”
NAME CITY
John New York
Emily New York
Amelia New York
•file3 =“完整列表_圣米格尔”
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();
有没有可以过滤所需数据的算法?
答案 0 :(得分:1)
您已经亲自编写了大部分优秀文章,现在您需要填补空白。 分解步骤
当然第一步是读取输入文件
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}");
}
}
}
您将获得理想的结果
答案 1 :(得分:1)
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将每一行转换为anonymous type的实例,以包含名称和城市。然后,GroupBy
用于按城市对这些实例进行分组。然后将每个组的数据写入一个新文件。
答案 2 :(得分:1)
我会通过在整个解决方案中保持相同的代码样式,来使@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
答案 3 :(得分:1)
这是一种使用字典的非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();
}