读取CSV文件并提取特定数据

时间:2015-06-05 15:10:36

标签: c# wpf csv

所以我有一个.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#的新手,所以我对内置类没有太多了解。任何帮助将不胜感激!

4 个答案:

答案 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();
}

输出: enter image description here

或者如果你想要,你可以通过这样做一次性完成这一切

 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(','));
}