一、合併簡介
在c#開發中,做數據處理時經常用到datatable,而那些單元格相等的datatable需要合併。合併是將一些行或列按照某種規則合併成新的行列,這樣做可以使數據變得更加整潔,方便我們運用。以下是介紹datatable合併的幾種方法:
二、按行合併
按照相鄰單元格的值,把同一行的單元格合併。比如將以下表格的行列合併,結果會得到新的二維表:
DataTable dt = CreateTable();
if(dt ==null)
{
Console.WriteLine("datatable為空");
return;
}
for(int i =0; i在這段代碼中,首先判斷datatable是否為空,之後就是按行遍歷整個datatable,把相鄰單元格的值相同的行合併起來。這做法比較簡單,但是只能實現單元格值相等的情況,且只支持按行合併,不能完成按列合併。
三、按列合併
對於按列合併,需要先使用pivot方法,將列轉化為行。以我們上一張表格為例,將其行列轉置後變成下圖:
之後按照相鄰單元格的值將列合併。以下是具體實現步驟:
DataTable dt = CreateTable();
if(dt == null) return;
//將列轉為行,並把新行插入dt中
DataTable newTable = new DataTable();
for(int i =0; i<dt.Columns.Count; i++)
{
DataRow newRow = newTable.NewRow();
newRow[0] = dt.Columns[i].ColumnName;
for(int j =0; j<dt.Rows.Count; j++)
{
string columnName = dt.Columns[i].ColumnName;
newRow[j+1] = dt.Rows[j][columnName];
}
newTable.Rows.Add(newRow);
}
//按列合併
for(int i =0; i=0; j--)
{
if(j-1>=0 && newTable.Rows[i][j-1].ToString() == newTable.Rows[i][j].ToString())
{
newTable.Rows[i][j-1] = newTable.Rows[i][j];
newTable.Columns.Remove(newTable.Columns[j]);
}
}
}
//將行轉回列
for(int i = 0; i<newTable.Columns.Count; i++)
{
DataRow newRow = dt.NewRow();
newRow[0] = newTable.Columns[i].ColumnName;
for(int j =1; j<newTable.Rows.Count; j++)
{
newRow[j] = newTable.Rows[j][i];
}
dt.Rows.Add(newRow);
}
該代碼首先將列轉化成行,之後遍歷新的datatable,按照相鄰單元格的值將列進行合併。最後再將行轉化回原來的列格式,合併過程就完成了。
四、按照特定列合併
在實際應用中,我們通常需要按照某些列進行合併,而不是將整個表進行合併。以下是針對具有「省份」和「城市」兩列的表格進行合併的代碼:
DataTable dt = CreateTable();
if (dt == null) return;
DataView dataView = dt.DefaultView;
dataView.Sort = "省份 asc, 城市 asc";
DataTable newTable = dataView.ToTable();
for (int i = newTable.Rows.Count - 1; i > 0; i--)
{
if (newTable.Rows[i]["省份"].ToString() == newTable.Rows[i - 1]["省份"].ToString() &&
newTable.Rows[i]["城市"].ToString() == newTable.Rows[i - 1]["城市"].ToString())
{
for (int j = 2; j <= newTable.Columns.Count - 1; j++)
{
if (newTable.Rows[i][j].ToString() != "")
newTable.Rows[i - 1][j] = newTable.Rows[i][j];
}
newTable.Rows.Remove(newTable.Rows[i]);
}
}
該代碼中,首先對datatable按照「省份」和「城市」兩列進行排序,並新建一個datatable達到排序的效果。之後遍歷排序後的datatable,按照「省份」和「城市」兩列進行合併。具體操作就是將相鄰的重複行的其他列進行合併。
五、按照正則表達式合併
另外,還可以按照正則表達式進行合併。以下是基於正則表達式進行datatable合併的代碼:
DataTable dt = CreateTable();
if (dt == null) return;
var regex = new Regex(@"[0-9]+");
var dict= new Dictionary<string, List<DataRow>>();
foreach(DataRow dr in dt.Rows)
{
foreach(DataColumn dc in dt.Columns)
{
var key = dc.ColumnName;
var match = regex.Match(dr[dc].ToString());
if(match.Success)
{
key+= match.Value;
}
if(dict.ContainsKey(key))
{
dict[key].Add(dr);
}
else
{
dict[key] = new List<DataRow>{dr};
}
}
}
var newTable = dt.Clone();
foreach(var group in dict)
{
var newRow = newTable.NewRow();
foreach(var col in newTable.Columns)
{
var colName = col.ToString();
if(colName.Contains("(+)"))
{
colName = colName.Replace("(+)", "").Trim();
var sum = 0;
foreach(var row in group.Value)
{
sum+= int.Parse(row[colName].ToString());
}
newRow[colName] = sum;
}
else
{
newRow[colName] = group.Value.FirstOrDefault()[colName];
}
}
newTable.Rows.Add(newRow);
}
這段代碼中,首先對每個單元格進行正則表達式匹配,匹配成功的列依據匹配的數字建立key,並把該行記錄加入到列表中。之後再根據key進行合併,遍歷相鄰相同的組的其他列進行合併。在這個例子中,我們要求的是列內的和,因此將「(+)」符號作為和的標誌,將相鄰相同組內的和加起來形成新的值。最後,代碼將合併後的datatable返回。
六、總結
上述就是針對datatable合併的幾種不同的方法,分別涉及到按行合併、按列合併、按照特定列合併、正則表達式等。實際應用中可能還會出現其他數據合併問題,需要按照具體情況進行不同的合併方法。綜上所述,datatable合併對於數據處理是必不可少的功能。
原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-tw/n/242734.html
微信掃一掃
支付寶掃一掃