在c#中将.csv中的不同列提取到不同的数组中

时间:2022-04-19 13:59:39

Background on this project. It started as a simple homework assignment that required me to store 5 zip codes and their corresponding cities. When a user puts a Zip code in a textbox, a corresponding city is returned, and likewise the opposite can be done. I wrote the code to return these values, but then I decided I wanted to store ALL zip codes and their corresponding Cities in an external .csv, and store those values in arrays and run the code off that because if its worth doing, its worth overdoing! To clarify, this is no longer for homework, just to learn more about using external files in C#.

背景在这个项目。一开始只是一个简单的家庭作业,我需要存储5个邮政编码和相应的城市。当用户在文本框中放置邮政编码时,将返回相应的城市,同样也可以执行相反的操作。我编写代码来返回这些值,但后来我决定将所有邮政编码和它们对应的城市存储在一个外部的.csv中,并将这些值存储在数组中并运行这些代码,因为如果值得这么做,那么就值得做得过火!澄清一下,这不再是家庭作业,只是学习更多关于在c#中使用外部文件的知识。

In the following code, I have called to open the file successfully, now I just need help in figuring out how to pull the data that is stored in two separate columns (one for city, one for zip code) and store them in two arrays to be acted upon by the for loop. Here is the code I have now. You can see how I have previously stored the other values in arrays and pulled them out:

在下面的代码,我已经被成功打开文件,现在我只是需要帮助解决如何把数据存储在两个不同的列(一个城市,一个邮政编码)并将它们存储在两个数组受到for循环。这是我现在的代码。你可以看到我之前是如何将其他值存储在数组中并将它们提取出来的:

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }

    private void btnConvert2City_Click(object sender, EventArgs e)
    {
        try
        {
            string dir = System.IO.Path.GetDirectoryName(
                System.Reflection.Assembly.GetExecutingAssembly().Location);

            string path = dir + @"\zip_code_database_edited.csv";
            var open = new StreamReader(File.OpenRead(path));

            int EnteredZipcode = Convert.ToInt32(txtZipcode.Text.Trim());
            string result = "No Cities Found";

            string[] Cities = new String[5] { "FLINTSTONE", "JAMAICA", "SCHENECTADY", "COTTONDALE", "CINCINNATI" };
            int[] Zipcode = new int[5] { 30725, 11432, 12345, 35453, 45263 };

            for (int i = 0; i <= Zipcode.Length - 1; i++)
            {
                if (Zipcode[i] == EnteredZipcode)
                {
                    result = Cities[i];
                    break;
                }
            }
            string DisplayState = result;
            txtCity.Text = DisplayState;
        }
        catch (FormatException)
        {
            MessageBox.Show("Input must be numeric value.");
        }
        catch (OverflowException)
        {
            MessageBox.Show("Zipcode to long. Please Re-enter");
        }
    }

    private void btnConvert2Zipcode_Click(object sender, EventArgs e)
    {
        string dir = System.IO.Path.GetDirectoryName(
                System.Reflection.Assembly.GetExecutingAssembly().Location);

        string path = dir + @"\zip_code_database_edited.csv";
        var open = new StreamReader(File.OpenRead(path));

        String EnteredCity = txtCity.Text.ToUpper();
        string result = "No Zipcode Found";

        string[] Cities = new String[5] { "FLINTSTONE", "JAMAICA", "SCHENECTADY", "COTTONDALE", "CINCINNATI" };
        int[] Zipcode = new int[5] { 30725, 11432, 12345, 35453, 45263 };

        for (int i = 0; i <= Cities.Length - 1; i++)
        {
            if (Cities[i] == EnteredCity)
            {
                result = Convert.ToString(Zipcode[i]);
                break;
            }
        }           
        string DisplayZip = result;
        txtZipcode.Text = DisplayZip;
    }       
}

The following data is a snippet of what the data in my excel .csv looks like:

以下数据是我的excel .csv中的数据的一个片段:

zip,primary_city
44273,Seville
44274,Sharon Center
44275,Spencer
44276,Sterling
44278,Tallmadge
44280,Valley City
44281,Wadsworth
44282,Wadsworth
44285,Wayland

And so on for about 46,000 rows.

大约有46000行。

How can I pull the zip and the primary_city into two separate arrays (I'm guessing with some ".Split "," "line) that my for-loop can operate on?

如何将zip和primary_city拉进两个独立的数组中(我想用一些)。分割“,”行)我的for循环可以操作吗?

Also, if there are better ways to go about this, please let me know (but be sure to leave an explanation as I want to understand where you are coming from).

另外,如果有更好的方法,请让我知道(但一定要留下一个解释,因为我想知道你从哪里来)。

3 个解决方案

#1


3  

Don't create two separate array.Create a separate class for city

不要创建两个单独的数组。为城市创建一个单独的类。

class City
{
    public string Name{get;set;}
    public int ZipCode{get;set;}
}

Now to read the data from that csv file

现在来读取csv文件中的数据

List<City> cities=File.ReadAllLines(path)
                      .Select(x=>new City
                         {
                              ZipCode=int.Parse(x.Split(',')[0]),
                              Name=x.Split(',')[1]
                         }).ToList<City>();

Or you can do this

或者你可以这么做

   List<City> cities=new List<City>();
   foreach(String s in File.ReadAllLines(path))
   {
       City temp=new City();
       temp.ZipCode=int.Parse(s.Split(',')[0]);
        temp.Name=s.Split(',')[1];
       cities.Add(temp);
   }

#2


1  

You can try this:

你可以试试这个:

    string dir = System.IO.Path.GetDirectoryName(
            System.Reflection.Assembly.GetExecutingAssembly().Location);

    string path = dir + @"\zip_code_database_edited.csv";
    var open = new StreamReader(File.OpenRead(path));
    var cities = new HashList<string>();
    var zipCodes = new HashList<int>();
    var zipAndCity = new string[2];
    string line = string.Empty;
    using (open)
{
        while ((line = reader.ReadLine()) != null)
        {
            zipAndCity = line.Split(",");
                zipCodes.Add(int.Parse(zipAndCity[0]));
                cities.Add(zipAndCity[1]);   
        }

}

#3


1  

I am posting this answer having learned much more about C# since I posted this question. When reading a CSV, there are better options than String.Split().

自从我发布这个问题以来,我已经学到了更多关于c#的知识。当读取CSV时,有比String.Split()更好的选项。

The .NET Framework already has a built-in dedicated CSV parser called TextFieldParser.

. net框架已经内置了一个名为TextFieldParser的专用CSV解析器。

It's located in the Microsoft.VisualBasic.FileIO namespace.

它位于Microsoft.VisualBasic中。FileIO名称空间。

Not only are there many edge cases that String.Split() is not properly equipped to handle, but it's also much slower to use StreamReader.

String.Split()不仅有许多边情况不能正确地进行处理,而且使用StreamReader也要慢得多。

#1


3  

Don't create two separate array.Create a separate class for city

不要创建两个单独的数组。为城市创建一个单独的类。

class City
{
    public string Name{get;set;}
    public int ZipCode{get;set;}
}

Now to read the data from that csv file

现在来读取csv文件中的数据

List<City> cities=File.ReadAllLines(path)
                      .Select(x=>new City
                         {
                              ZipCode=int.Parse(x.Split(',')[0]),
                              Name=x.Split(',')[1]
                         }).ToList<City>();

Or you can do this

或者你可以这么做

   List<City> cities=new List<City>();
   foreach(String s in File.ReadAllLines(path))
   {
       City temp=new City();
       temp.ZipCode=int.Parse(s.Split(',')[0]);
        temp.Name=s.Split(',')[1];
       cities.Add(temp);
   }

#2


1  

You can try this:

你可以试试这个:

    string dir = System.IO.Path.GetDirectoryName(
            System.Reflection.Assembly.GetExecutingAssembly().Location);

    string path = dir + @"\zip_code_database_edited.csv";
    var open = new StreamReader(File.OpenRead(path));
    var cities = new HashList<string>();
    var zipCodes = new HashList<int>();
    var zipAndCity = new string[2];
    string line = string.Empty;
    using (open)
{
        while ((line = reader.ReadLine()) != null)
        {
            zipAndCity = line.Split(",");
                zipCodes.Add(int.Parse(zipAndCity[0]));
                cities.Add(zipAndCity[1]);   
        }

}

#3


1  

I am posting this answer having learned much more about C# since I posted this question. When reading a CSV, there are better options than String.Split().

自从我发布这个问题以来,我已经学到了更多关于c#的知识。当读取CSV时,有比String.Split()更好的选项。

The .NET Framework already has a built-in dedicated CSV parser called TextFieldParser.

. net框架已经内置了一个名为TextFieldParser的专用CSV解析器。

It's located in the Microsoft.VisualBasic.FileIO namespace.

它位于Microsoft.VisualBasic中。FileIO名称空间。

Not only are there many edge cases that String.Split() is not properly equipped to handle, but it's also much slower to use StreamReader.

String.Split()不仅有许多边情况不能正确地进行处理,而且使用StreamReader也要慢得多。