You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C#实现拆分DataTable中分号拼接列生成新DataTable

解决DataTable多列分号分隔元素拆分问题

我来帮你搞定这个DataTable拆分的需求!你的核心目标是把logistique、amount等列中用分号拼接的元素拆分成单独行,同时保留原行其他列的数值,对吧?你当前的代码问题在于条件判断过于复杂混乱,不仅逻辑有误,还会重复生成不必要的行。下面是修正后的方案:

核心思路

  1. 克隆原DataTable的结构,确保新表和原表列完全一致
  2. 遍历原表每一行,提取不需要拆分的固定列值(produit、test1、test3)
  3. 将需要拆分的列按分号拆分为字符串数组,同时处理可能的空值情况
  4. 计算所有拆分数组的最大长度,以此作为循环次数,保证每个元素都能生成对应行
  5. 针对每个索引位置,为拆分列赋值:若索引在数组范围内则取对应元素,否则赋值为null(或空字符串,可按需调整)
  6. 将固定列值和处理后的拆分列值一起添加到新表中

修正后的完整代码

using System;
using System.Data;
using System.Linq;

namespace ConsoleApplication9
{
    class Program
    {
        static void Main(string[] args)
        {
            // 初始化原DataTable
            DataTable dt1 = new DataTable();
            dt1.Columns.Add("produit", typeof(string));
            dt1.Columns.Add("test1", typeof(int));
            dt1.Columns.Add("test3", typeof(int));
            dt1.Columns.Add("logistique", typeof(string));
            dt1.Columns.Add("amount", typeof(string));
            dt1.Columns.Add("testAjout", typeof(string));
            dt1.Columns.Add("testAjout1", typeof(string));
            dt1.Rows.Add(new object[] { "P1", 1, 3, "t3;t1;t2", "t4;t5;t6;tr", "T34;T25", "Rahima;T33;T55;T66" });
            dt1.Rows.Add(new object[] { "P2", 1, 4, "t9;t10;t55", "t2;t1;t3", "t34;t45", "Nadji" });

            // 克隆原表结构,创建新表
            DataTable dt2 = dt1.Clone();

            foreach (DataRow row in dt1.AsEnumerable())
            {
                // 提取固定列的值
                string produit = row.Field<string>("produit");
                int test1 = row.Field<int>("test1");
                int test3 = row.Field<int>("test3");

                // 拆分需要处理的列,空值时返回空数组避免报错
                string[] splitLogistique = row.Field<string>("logistique")?.Split(';') ?? Array.Empty<string>();
                string[] splitAmount = row.Field<string>("amount")?.Split(';') ?? Array.Empty<string>();
                string[] splitAjout = row.Field<string>("testAjout")?.Split(';') ?? Array.Empty<string>();
                string[] splitAjout1 = row.Field<string>("testAjout1")?.Split(';') ?? Array.Empty<string>();

                // 计算所有拆分数组的最大长度,确保每个元素都能生成对应行
                int maxLength = new[] { splitLogistique.Length, splitAmount.Length, splitAjout.Length, splitAjout1.Length }.Max();

                for (int i = 0; i < maxLength; i++)
                {
                    // 为每个拆分列赋值,索引超出范围则设为null
                    string logistiqueVal = i < splitLogistique.Length ? splitLogistique[i] : null;
                    string amountVal = i < splitAmount.Length ? splitAmount[i] : null;
                    string ajoutVal = i < splitAjout.Length ? splitAjout[i] : null;
                    string ajout1Val = i < splitAjout1.Length ? splitAjout1[i] : null;

                    // 添加新行到新表
                    dt2.Rows.Add(produit, test1, test3, logistiqueVal, amountVal, ajoutVal, ajout1Val);
                }
            }

            // 输出结果验证
            foreach (DataRow row in dt2.Rows)
            {
                foreach (DataColumn col in dt2.Columns)
                {
                    Console.Write($"\t{row[col] ?? "(空)"}");
                }
                Console.WriteLine();
            }
        }
    }
}

原代码的问题说明

你之前的代码中,多个if条件会同时触发(比如当索引超出某一个数组长度时,多个条件判断都会成立),导致同一索引位置生成多行重复数据,完全不符合“每个元素单独占一行”的需求。修正后的代码通过统一的循环和索引判断,逻辑清晰且能准确生成所需的行。

内容的提问来源于stack exchange,提问作者lili1986

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 09:01:06