我想要转换为CSV字符串格式的double[][]
(即一行中的每一行,以逗号分隔的行元素)。我是这样写的:
public static string ToCSV(double[][] array)
{
return String.Join(Environment.NewLine,
Array.ConvertAll(array,
row => String.Join(",",
Array.ConvertAll(row, x => x.ToString())));
}
使用LINQ写一个更优雅的方法吗?
(我知道,可以使用临时变量来使它看起来更好,但这种代码格式更能传达我想要的东西。)
答案 0 :(得分:6)
你可以,但我不会亲自做所有的行 - 我会使用迭代器块:
public static IEnumerable<string> ToCSV(IEnumerable<double[]> source)
{
return source.Select(row => string.Join(",",
Array.ConvertAll(row, x=>x.ToString())));
}
这会返回每一行(调用者可以有效地WriteLine
等,而不会缓冲所有内容)。它现在也可以从double[]
行的任何来源调用(包括但不限于锯齿状数组)。
此外 - 使用本地变量,您可以使用StringBuilder
使每一行稍微便宜一些。
要立即返回整个字符串,我会优化它以使用单个StringBuilder
进行所有字符串工作;有点啰嗦,但更有效率(更少的中间字符串):
public static string ToCSV(IEnumerable<double[]> source) {
StringBuilder sb = new StringBuilder();
foreach(var row in source) {
if (row.Length > 0) {
sb.Append(row[0]);
for (int i = 1; i < row.Length; i++) {
sb.Append(',').Append(row[i]);
}
}
}
return sb.ToString();
}
答案 1 :(得分:2)
您也可以使用Aggregate
public static string ToCSV(double[][] array)
{
return array.Aggregate(string.Empty, (multiLineStr, arrayDouble) =>
multiLineStr + System.Environment.NewLine +
arrayDouble.Aggregate(string.Empty, (str, dbl) => str + "," + dbl.ToString()));
}
答案 2 :(得分:1)
你可以用LINQ做到,但我不确定你是否比你更喜欢这个。我怕你没有。 :)
var q = String.Join(Environment.NewLine, (from a in d
select String.Join(", ", (from b in a
select b.ToString()).ToArray())).ToArray());
干杯, 的Matthias
答案 3 :(得分:1)
这与double
的任何嵌套序列兼容。它还将ToString
实现推迟到调用者,允许格式化,同时避免凌乱的IFormatProvider
重载:
public static string Join(this IEnumerable<string> source, string separator)
{
return String.Join(separator, source.ToArray());
}
public static string ToCsv<TRow>(this IEnumerable<TRow> rows, Func<double, string> valueToString)
where TRow : IEnumerable<double>
{
return rows
.Select(row => row.Select(valueToString).Join(", "))
.Join(Environment.NewLine);
}