如何根据列将单行值拆分为多行 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;
});
}
}
}
我有一个很大的 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;
});
}
}
}