[英]Can I rewrite this more elegantly using LINQ?
I have a double[][]
that I want to convert to a CSV string format (ie each row in a line, and row elements separated by commas).我有一个double[][]
我想转换为 CSV 字符串格式(即一行中的每一行,行元素用逗号分隔)。 I wrote it like this:我是这样写的:
public static string ToCSV(double[][] array)
{
return String.Join(Environment.NewLine,
Array.ConvertAll(array,
row => String.Join(",",
Array.ConvertAll(row, x => x.ToString())));
}
Is there a more elegant way to write this using LINQ?有没有更优雅的方式来使用 LINQ 编写这个?
(I know, one could use temporary variables to make this look better, but this code format better conveys what I am looking for.) (我知道,可以使用临时变量来使它看起来更好,但这种代码格式更好地传达了我正在寻找的内容。)
You can, but I wouldn't personally do all the lines at once - I'd use an iterator block:你可以,但我个人不会一次完成所有的行——我会使用迭代器块:
public static IEnumerable<string> ToCSV(IEnumerable<double[]> source)
{
return source.Select(row => string.Join(",",
Array.ConvertAll(row, x=>x.ToString())));
}
This returns each line (the caller can then WriteLine
etc efficiently, without buffering everything).这将返回每一行(调用者可以有效地WriteLine
等,而无需缓冲所有内容)。 It is also now callable from any source of double[]
rows (including but not limited to a jagged array).它现在也可以从任何double[]
行来源(包括但不限于锯齿状数组)调用。
Also - with a local variable you could use StringBuilder
to make each line slightly cheaper.另外 - 使用局部变量,您可以使用StringBuilder
使每行稍微便宜一些。
To return the entire string at once, I'd optimize it to use a single StringBuilder
for all the string work;为了一次返回整个字符串,我会优化它以使用单个StringBuilder
来完成所有字符串工作; a bit more long-winded, but much more efficient (far fewer intermediate strings):有点冗长,但效率更高(中间字符串少得多):
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();
}
You could also use 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()));
}
You can do it with LINQ, but I'm not sure if you like this one better than yours.你可以用 LINQ 做到这一点,但我不确定你是否比你更喜欢这个。 I'm afraid you don't.恐怕你不会。 :) :)
var q = String.Join(Environment.NewLine, (from a in d
select String.Join(", ", (from b in a
select b.ToString()).ToArray())).ToArray());
Cheers, Matthias干杯,马蒂亚斯
This is compatible with any nested sequences of double
.这与任何嵌套的double
序列兼容。 It also defers the ToString
implementation to the caller, allowing formatting while avoiding messy IFormatProvider
overloads:它还将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);
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.