所以我有一个.CSV文件,可能有数百万甚至数十亿行数据。数据采用以下格式:
1,,5,6,7,82,4,6
1,4,4,5,6,33,4,
2,6,3,,6,32,6,7
,,,2,5,45,,6
,4,5,6,,33,5,6
我想要实现的是:让我们假设每行数据都是一个“事件”。让我们称之为。现在让我们说一个用户说,向我展示第6个值为33的所有事件。你可以看到上面的第6个数据元素是一个2位数字,用户可以说给我看第6个数据元素是33的所有事件和输出将是:
1,4,4,5,6,33,4,
,4,5,6,,33,5,6
另外,正如你所看到的那样。数据可能有数据缺失的空白或漏洞。我不需要帮助阅读.CSV文件或任何东西。我无法理解如何访问第6个数据元素。此外,我更喜欢这个输出是否在某种集合中表示。我是C#的新手,所以我对内置类没有太多了解。任何帮助将不胜感激!
答案 0 :(得分:1)
我建议不要使用term" event"更常见地将这种数据结构称为"行和列"并使用C#Split()
函数创建2d-array(string[,]
或int[,]
),其中每个元素可通过其行/列索引方便地访问,并将任何业务逻辑应用于这些元素
CSV文件阅读器的可能实现(按行显示,每行存储在List<string> listRows
中)如下所示(re:Reading CSV file and storing values into an array)
using System.IO;
static void Main(string[] args)
{
var reader = new StreamReader(File.OpenRead(@"C:\YouFile.csv"));
List<string> listRows= new List<string>();
while (!reader.EndOfStream)
{
listRows.Add(reader.ReadLine());
}
}
然后将Split(',')
函数应用于每一行(存储在listRows
中)以组成二维数组string[,]
并使用int.TryParse()
方法将其转换为类型{{1 (必要时可选)。
或者,这可以通过使用LINQ库来实现,由于技术表面区域的不必要扩展,以及可能的性能下降(LINQ解决方案预计比建议的直接处理慢),不推荐使用LINQ库。
希望这可能会有所帮助。
答案 1 :(得分:1)
使用Linq很容易实现。我是从LinqPad发布样本并提供输出的。您需要做的就是用参数替换33:
void Main()
{
string csvFile = @"C:\Temp\TestData.csv";
string[] lines = File.ReadAllLines(csvFile);
var values = lines.Select(s => new { myRow = s.Split(',')});
//and here is your collection representing results
List<string[]> results = new List<string[]>();
foreach (var value in values)
{
if(value.Values.Contains("33")){
results.Add(value.myRow);
}
}
results.Dump();
}
输出:
或者如果你想要,你可以通过这样做一次性完成这一切
string csvFile = @"C:\Temp\TestData.csv";
string[] lines = File.ReadAllLines(csvFile);
var values = lines.Select(s =>
new {Position =Array.FindIndex(s.Split(','),a=>a.Contains("33"))+1
,myRow = s.Split(',')
});
所以最终产品将同时具有搜索位置(33)和项目的完整字符串[]。
答案 2 :(得分:0)
创建一个班级EventEntity
。在这个类中创建一个List<int>
,其中包含一个初始化列表的构造函数。这是一个类示例:
public class EventEntity
{
public EventEntity()
{
EventList = new List<int>();
}
public List<int> EventList { get; set; }
}
从那里循环遍历每一行数据。例如:
public class EventEntityRepo
{
public EventEntity GetEventEntityByCsvDataRow(String[] csvRow)
{
EventEntity events = new EventEntity();
foreach (String csvCell in csvRow)
{
int eventId = -1;
if(csvCell != null && csvCell != String.Empty)
{
try
{
eventId = Convert.ToInt32(csvCell.Trim());
}
catch (Exception ex)
{
//failed to parse int
}
}
events.EventList.Add(eventId); //if an empty item, insert -1
}
return events;
}
}
然后您可以随时引用这些项目。
eventEntityList = GetEventEntityByCsvDataRow(csvDataRow);
eventEntitySixthElement = eventEntityList[5];
答案 3 :(得分:0)
所以你的问题是如何访问第6个数据元素。如果你有正确的数据结构代表你的csv,那就不难了。
基本上这个抽象术语中的csv文档可以描述为IEnumerable<IEnumerable<String>>
,或者可能是IEnumerable<IEnumerable<int?>>
。实现了csv解析逻辑后,您将通过executin访问第6个元素:
var csvRepresenation = ParseCsv(@"D:/file.csv");
var element = csvRepresentation.ElementAt(6);
if (element == "6")
{
// do smth
}
通过这种方法,您还可以在其上执行Linq语句。
现在的问题是如何实施ParseCsv()
:
public IEnumerable<IEnumerable<String>> ParseCsv(string path)
{
return File.ReadAllLines(path).Select(row => row.Split(','));
}