對于String.Join(String, String[])這個方法,相信大家都有所了解。唯一不足的就是這個方法只能用于字符串數(shù)組,適用場景比較少。我所遇到的場景中,更多的是對List
實現(xiàn)的方式是對IEnumerable
成都創(chuàng)新互聯(lián)公司專注于城步企業(yè)網(wǎng)站建設,響應式網(wǎng)站設計,商城建設。城步網(wǎng)站建設公司,為城步等地區(qū)提供建站服務。全流程定制網(wǎng)站開發(fā),專業(yè)設計,全程項目跟蹤,成都創(chuàng)新互聯(lián)公司專業(yè)和態(tài)度為您提供的服務
///
/// 將數(shù)組合并成字符串,Action< ,TextWriter>
///
///
///
///
///
///
public static void Join(this IEnumerable enumerable,String separator,Action action,TextWriter output)
{
Func writeSp = (x, y) => { x.Write(y); return true; };
IEnumerator en = enumerable.GetEnumerator();
if(en.MoveNext())
{
do
{
action(en.Current,output);
} while(en.MoveNext() && writeSp(output, separator));
}
}
///
/// 將數(shù)組合并成字符串,Action< >
///
///
///
///
///
///
public static void Join(this IEnumerable enumerable,String separator,Action action,TextWriter output)
{
Func writeSp = (x, y) => { x.Write(y); return true; };
IEnumerator en = enumerable.GetEnumerator();
if(en.MoveNext())
{
do
{
action(en.Current);
} while(en.MoveNext() && writeSp(output, separator));
}
}
下面通過實現(xiàn)“DataTable轉(zhuǎn)CSV”來對這兩個方法和嵌套For循環(huán)進行對比。
在這個Demo里,DataTable有3列100行數(shù)據(jù)。對3種實現(xiàn)方式分別進行10000、100000和1000000循環(huán)。
Demo:
[TestMethod]
public void TestMethod5()
{
DataTable dt = new DataTable("1234");
dt.Columns.Add("A");
dt.Columns.Add("B");
dt.Columns.Add("C");
for(int i = 0; i < 100; i++)
{
dt.Rows.Add("A" + i, "B" + i, "C" + i);
}
StringBuilder sb;//= new StringBuilder();
StringWriter sw;// = new StringWriter(sb);
String rowSeparator = "\n";
String columnSeparator = ",";
//Console.WriteLine(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss:ffffff"));
DateTime time1 = DateTime.Now;
Int32 count = 1000000;
for(int c = 0; c < count; c++)
{
sb = new StringBuilder();
sw = new StringWriter(sb);
#region Action
// var columns = dt.Columns.OfType();
//// 寫標題
//columns.Join(columnSeparator, (x) => x.ColumnName, sw);
//sw.Write(rowSeparator);
//// 寫數(shù)據(jù)
//dt.Select().Join(rowSeparator, (x, x1) => columns.Join(columnSeparator, (y, y1) => { y1.Write('"'); y1.Write(x[y]); y1.Write('"'); }, x1), sw);
#endregion
#region Action
// var columns = dt.Columns.OfType();
//columns.Join(columnSeparator, (x) => sw.Write(x.ColumnName), sw);
//sw.Write(rowSeparator);
//dt.Select().Join(rowSeparator, (x) => columns.Join(columnSeparator, (y) => { sw.Write('"'); sw.Write(x[y]); sw.Write('"'); }, sw), sw);
#endregion
#region 嵌套for
Func func = (x, y) => { x.Write(y); return true; };
sb = new StringBuilder();
for(int i = 0; i < dt.Columns.Count && func(sw, columnSeparator); i++)
{
sw.Write(dt.Columns[i].ColumnName);
}
sw.Write(rowSeparator);
for(int i = 0; i < dt.Rows.Count && func(sw, rowSeparator); i++)
{
for(int j = 0; j < dt.Columns.Count && func(sw, columnSeparator); j++)
{
sw.Write('"');
sw.Write(dt.Rows[i][j]);
sw.Write('"');
}
}
#endregion
sw.Flush();
sw.Close();
//Console.WriteLine(sb.ToString());
}
//Console.WriteLine(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss:ffffff"));
DateTime time2 = DateTime.Now;
Console.WriteLine($"{time1.ToString("yyyy-MM-dd HH:mm:ss:ffffff")}\t{time2.ToString("yyyy-MM-dd HH:mm:ss:ffffff")}\t{time2.Ticks - time1.Ticks}");
}
測試結(jié)果:
類別 | 循環(huán)次數(shù) | 開始時間 | 結(jié)束時間 | Ticks差 |
---|---|---|---|---|
Action |
10000 | 2018-11-05 22:13:58:619431 | 2018-11-05 22:14:01:708661 | 30862597 |
Action |
10000 | 2018-11-05 22:30:01:316414 | 2018-11-05 22:30:04:540565 | 32241503 |
嵌套for | 10000 | 2018-11-05 22:48:20:351136 | 2018-11-05 22:48:23:832171 | 34810345 |
Action |
100000 | 2018-11-05 22:17:45:756623 | 2018-11-05 22:18:14:361243 | 286046197 |
Action |
100000 | 2018-11-05 22:30:38:917299 | 2018-11-05 22:31:08:680268 | 297629687 |
嵌套for | 100000 | 2018-11-05 22:50:11:315021 | 2018-11-05 22:50:45:257604 | 339425834 |
Action |
1000000 | 2018-11-05 22:19:02:489665 | 2018-11-05 22:24:06:528472 | 3040388071 |
Action |
1000000 | 2018-11-05 22:32:09:871650 | 2018-11-05 22:37:05:125522 | 2952538718 |
嵌套for | 1000000 | 2018-11-05 22:51:18:319466 | 2018-11-05 22:56:46:534431 | 3282149643 |
從結(jié)果中可以看出,性能差距并不大。當然,由于嵌套For循環(huán)里使用索引來尋值,所以可能存在誤差。
如果有錯誤或者更好的方法,歡迎指正。
題外話,方法命名為Join,可能與Linq的Join存在歧義,建議使用時換成其他名稱。