【问题标题】:How to split single row values into multiple rows based on columns c#如何根据列c#将单行值拆分为多行
【发布时间】:2021-02-19 17:59:50
【问题描述】:

我有一个大型 csv 文件,其中有多个属于不同人的值存储在同一行中。您可以在下面找到该数据的示例。

country country2 country3 name1 name2 name3 phone1 phone2 phone3
USA UK Australia Michael Mitchell David 222 333 444
Colombia Paraguay Bolivia John Chris 555 7777
Brazil Germany Japan Silvia Ana 888 999

我想拆分这些数据,这样我就可以保持前 3 列不变,只格式化其余的列,这意味着我将保留国家、国家 2 和国家 3 的格式,但姓名和电话只会出现一次。这个想法是,同一行中的每个人最后都将拥有相同的 3 个国家/地区,但其数据将在单独的行中查看,以便如下所示:

country country2 country3 name phone
USA UK Australia Michael 222
USA UK Australia Mitchell 333
USA UK Australia David 444
Colombia Paraguay Bolivia
Colombia Paraguay Bolivia John 555
Colombia Paraguay Bolivia Chris 7777
Brazil Germany Japan Silvia 888
Brazil Germany Japan Ana 999
Brazil Germany Japan

我已经看到了一些基于 SQL 的示例,但我正在尝试在 C# 上完成此操作,因为我需要以这种特定方式设置数据,以便在将其发送到数据库之前使用它做一些其他事情。我目前将数据存储到数据表中,但我不确定如何在不影响数据不一致的情况下进行此更改。有什么想法吗?

编辑: 这是我到目前为止仅将此数据发送到数据表的代码:

    public static DataTable ConvertCSVtoDataTable(string strFilePath)
    {
        DataTable dt = new DataTable();
        using (StreamReader sr = new StreamReader(strFilePath))
        {
            string[] headers = sr.ReadLine().Split(',');
            foreach (string header in headers)
            {
                dt.Columns.Add(header);
            }
            while (!sr.EndOfStream)
            {
                string[] rows = sr.ReadLine().Split(',');
                DataRow dr = dt.NewRow();
                for (int i = 0; i < headers.Length; i++)
                {
                    dr[i] = rows[i];
                }
                dt.Rows.Add(dr);
            }
        }
        return dt;
    }

【问题讨论】:

  • 欢迎来到 SO。您能否展示一下您尝试过的minimal reproducible example 并解释它是如何不起作用的?
  • 嗨,到目前为止,我只是将值存储到具有以下功能的数据表中。我知道我可以创建另一个可以开始逐行填写数据的数据表,但我仍然不确定如何指示此函数在跳转到名称 2 和电话之前首先只选择名称为 1 和电话 1 的列值2 以此类推。
  • DataTable dt = new DataTable();使用 (StreamReader sr = new StreamReader(strFilePath)) { string[] headers = sr.ReadLine().Split(','); foreach(标题中的字符串标题){ dt.Columns.Add(header); } while (!sr.EndOfStream) { string[] rows = sr.ReadLine().Split(',');数据行博士 = dt.NewRow(); for (int i = 0; i
  • edit您的问题并在那里添加信息。在 cmets 中读取长段代码效果不是很好,而且它也是问题的基本信息,因此它更适合问题。
  • 好的,我补充一点没问题。

标签: c# csv datatable multiple-columns rows


【解决方案1】:

我希望您的测试 csv 文件看起来像这样:

USA;UK;Australia;Michael;Mitchell;David;222;333;444
Colombia;Paraguay;Bolivia;;John;Chris;;555;7777
Brazil;Germany;Japan;Silvia;Ana;;888;999;;

你会在modifiedData变量中得到你想要的:

using System.Collections.Generic;
using System.IO;

namespace CsvMod
{
    public class OriginalData
    {
        public string Country1 { get; set; }
        public string Country2 { get; set; }
        public string Country3 { get; set; }
        public string Name1 { get; set; }
        public string Name2 { get; set; }
        public string Name3 { get; set; }
        public string Phone1 { get; set; }
        public string Phone2 { get; set; }
        public string Phone3 { get; set; }
    }

    public class ModifiedData
    {
        public string Country1 { get; set; }
        public string Country2 { get; set; }
        public string Country3 { get; set; }
        public string Name { get; set; }
        public string Phone { get; set; }
    }

    class Program
    {
        static void Main(string[] args)
        {
            var csvLines = File.ReadAllLines("test.csv");

            var originalData = new List<OriginalData>();

            foreach (var line in csvLines)
            {
                var items = line.Split(';');

                originalData.Add(new OriginalData
                {
                    Country1 = items[0],
                    Country2 = items[1],
                    Country3 = items[2],
                    Name1 = items[3],
                    Name2 = items[4],
                    Name3 = items[5],
                    Phone1 = items[6],
                    Phone2 = items[7],
                    Phone3 = items[8],
                });
            }

            var modifiedData = new List<ModifiedData>();

            foreach (var item in originalData)
            {
                modifiedData.AddRange(new List<ModifiedData>
                {
                    new ModifiedData
                    {
                        Country1 = item.Country1,
                        Country2 = item.Country2,
                        Country3 = item.Country3,
                        Name = item.Name1,
                        Phone = item.Phone1,
                    },
                    new ModifiedData
                    {
                        Country1 = item.Country1,
                        Country2 = item.Country2,
                        Country3 = item.Country3,
                        Name = item.Name2,
                        Phone = item.Phone2,
                    },
                    new ModifiedData
                    {
                        Country1 = item.Country1,
                        Country2 = item.Country2,
                        Country3 = item.Country3,
                        Name = item.Name3,
                        Phone = item.Phone3,
                    },
                });
            }
        }
    }
}

或者,如果您真的信任您的数据,那么一条 LINQ 语句和 result 包含相同的内容:

using System.Collections.Generic;
using System.IO;
using System.Linq;

namespace CsvMod
{
    public class ModifiedData
    {
        public string Country1 { get; set; }
        public string Country2 { get; set; }
        public string Country3 { get; set; }
        public string Name { get; set; }
        public string Phone { get; set; }
    }

    class Program
    {
        static void Main(string[] args)
        {
            var csvLines = File.ReadAllLines("test.csv");

            var result = csvLines.Aggregate(new List<ModifiedData>(), (acc, x) =>
            {
                var items = x.Split(';');

                acc.AddRange(new List<ModifiedData>
                {                    
                    new ModifiedData
                    {
                        Country1 = items[0],
                        Country2 = items[1],
                        Country3 = items[2],
                        Name = items[3],
                        Phone = items[6],
                    },
                    new ModifiedData
                    {
                        Country1 = items[0],
                        Country2 = items[1],
                        Country3 = items[2],
                        Name = items[4],
                        Phone = items[7],
                    },
                    new ModifiedData
                    {
                        Country1 = items[0],
                        Country2 = items[1],
                        Country3 = items[2],
                        Name = items[5],
                        Phone = items[8],
                    },
                });

                return acc;
            });
        }
    }
}

【讨论】:

  • 一点也不,我已经更新了答案,所以如果你有时间,你可以学习 LINQ,有时它有助于使处理可枚举数据更容易! :)
猜你喜欢
  • 2020-02-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-04-10
  • 2023-04-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多