3

double[][]CSV 文字列形式 (つまり、行内の各行、およびコンマで区切られた行要素) に変換したいものがあります。私は次のように書きました:

public static string ToCSV(double[][] array)
{
    return String.Join(Environment.NewLine,
                       Array.ConvertAll(array,
                                        row => String.Join(",",
                                                           Array.ConvertAll(row, x => x.ToString())));
}

LINQ を使用してこれを記述するよりエレガントな方法はありますか?

(一時変数を使用して見栄えを良くすることもできますが、このコード形式の方が探しているものをよりよく伝えます。)

4

4 に答える 4

6

できますが、個人的には一度にすべての行を実行するつもりはありません。イテレータ ブロックを使用します。

public static IEnumerable<string> ToCSV(IEnumerable<double[]> source)
{
    return source.Select(row => string.Join(",",
       Array.ConvertAll(row, x=>x.ToString())));        
}

これにより、各行が返されます(呼び出し元は、WriteLineすべてをバッファリングすることなく、効率的に etc できます)。また、任意の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();
}
于 2009-02-25T09:01:48.263 に答える
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()));
}
于 2009-02-26T00:47:43.620 に答える
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);
}
于 2009-02-26T06:23:07.403 に答える
1

あなたはLINQでそれを行うことができますが、これがあなたのものよりも好きかどうかはわかりません. 私はあなたがしないことを恐れています。:)

var q = String.Join(Environment.NewLine, (from a in d
                                      select String.Join(", ", (from b in a
                                                                select b.ToString()).ToArray())).ToArray());

乾杯、マティアス

于 2009-02-25T09:08:53.673 に答える