一、合併簡介
在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-hk/n/242734.html