首页 > 解决方案 > 如何根据列c#将单行值拆分为多行

问题描述

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

国家 国家2 国家3 名称1 名称2 名称3 电话1 电话2 电话3
美国 英国 澳大利亚 迈克尔 米切尔 大卫 222 333 444
哥伦比亚 巴拉圭 玻利维亚 约翰 克里斯 555 7777
巴西 德国 日本 西尔维娅 安娜 888 999

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

国家 国家2 国家3 姓名 电话
美国 英国 澳大利亚 迈克尔 222
美国 英国 澳大利亚 米切尔 333
美国 英国 澳大利亚 大卫 444
哥伦比亚 巴拉圭 玻利维亚
哥伦比亚 巴拉圭 玻利维亚 约翰 555
哥伦比亚 巴拉圭 玻利维亚 克里斯 7777
巴西 德国 日本 西尔维娅 888
巴西 德国 日本 安娜 999
巴西 德国 日本

我已经看到了一些基于 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;
    }

标签: c#csvdatatablemultiple-columnsrows

解决方案


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

推荐阅读