如何根据列将单行值拆分为多行 C#

How to split single row values into multiple rows based on columns c#

我有一个很大的 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 列不变,只对其余列进行格式化,这意味着我将保留 country、country2 和 country3 的格式,但名称和 phone 会出现就一次。这个想法是来自同一行的每个人最后都会有相同的 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;
    }

我希望您的测试 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;
            });
        }
    }
}