0

同じ長さの 2 番目の配列を条件として、値 (double) の配列内の要素に対して平均または合計または別の方法を計算したいと思います。

たとえば、日付 (double[]dts) を含む並べ替えられた配列があり、値の配列 (double[]vals) (つまり、シンプルで、以下の私のコードは何をしますか)。

しかし、たとえば、1 年間のすべての月曜日の平均を計算したい場合、以下のコードは機能しなくなります。何か案は?ありがとう!

public static double aggr(double[] dts, double[] vals, double std, double edd)
    {
        int stdindex = 0;
        int eddindex = dts.Length;

        for (int k = 0; k < dts.Length; k++)
        {
            if (dts[k] == std)
            {
                stdindex = k;
            }
            if (dts[k] == edd)
            {
                eddindex = k;
            }
        }


        return vals.Skip(stdindex).Take(eddindex-stdindex).Average();
    }

みんなありがとう。すべての答えがうまくいくと思います。これが私の新しいコードです:

 public static double aggr(double[] dts, double[] vals, double std, double edd, string peakoffpeakbase, double sumavg)
    {
        double result;
        if (sumavg == 1)
        {

            if (peakoffpeakbase=="Peak")
            {
                    result = dts.Zip(vals, (d, v) => new { d, v })
                                        .Where(dv =>  (dv.d >= std & dv.d < edd & DateTime.FromOADate(dv.d).DayOfWeek != DayOfWeek.Saturday & DateTime.FromOADate(dv.d).DayOfWeek != DayOfWeek.Sunday & DateTime.FromOADate(dv.d).Hour > 7 & DateTime.FromOADate(dv.d).Hour < 20))
                                        .Select(dv => dv.v).Sum();
            }
             else if (peakoffpeakbase=="Offpeak")
            {
                    result = dts.Zip(vals, (d, v) => new { d, v })
                                        .Where(dv => (dv.d >= std & dv.d < edd & DateTime.FromOADate(dv.d).DayOfWeek == DayOfWeek.Saturday | DateTime.FromOADate(dv.d).DayOfWeek == DayOfWeek.Sunday | DateTime.FromOADate(dv.d).Hour < 8 | DateTime.FromOADate(dv.d).Hour > 19))
                                        .Select(dv => dv.v).Sum();
             }
             else
             {
                    result = dts.Zip(vals, (d, v) => new { d, v })
                                       .Where(dv => (dv.d >= std && dv.d < edd))
                                       .Select(dv => dv.v).Sum();
            }
        }

        else
        {

            if (peakoffpeakbase == "Peak")
            {
                result = dts.Zip(vals, (d, v) => new { d, v })
                                    .Where(dv => (dv.d >= std & dv.d < edd & DateTime.FromOADate(dv.d).DayOfWeek != DayOfWeek.Saturday & DateTime.FromOADate(dv.d).DayOfWeek != DayOfWeek.Sunday & DateTime.FromOADate(dv.d).Hour > 7 & DateTime.FromOADate(dv.d).Hour < 20))
                                    .Select(dv => dv.v).Average();
            }
            else if (peakoffpeakbase == "Offpeak")
            {
                result = dts.Zip(vals, (d, v) => new { d, v })
                                    .Where(dv => (dv.d >= std & dv.d < edd & (DateTime.FromOADate(dv.d).DayOfWeek == DayOfWeek.Saturday | DateTime.FromOADate(dv.d).DayOfWeek == DayOfWeek.Sunday | DateTime.FromOADate(dv.d).Hour < 8 | DateTime.FromOADate(dv.d).Hour > 19)))
                                    .Select(dv => dv.v).Average();
            }
            else
            {
                result = dts.Zip(vals, (d, v) => new { d, v })
                                   .Where(dv => (dv.d >= std && dv.d < edd))
                                   .Select(dv => dv.v).Average();
            }
        }
            return result;

    }

明らかに、これはひどく、非常に冗長です。私が本当にやりたいことは、以下の答えを組み合わせて、次のように書くことです。

result = dts.Zip(vals, (d, v) => new { d, v })
                                        .Where(dv =>  (dv.d.InTimeRange(std,edd).IsBusinessHour(peakoffpeakbase))
                                        .Select(dv => dv.v).CustomX(indicator);

InTimeRange と IsBusinessHour は以下で説明する拡張メソッドであり、customX は引数を取り、次に平均、合計、または sth を実行します。しかし、私はそれを機能させることができません。再度、感謝します!

4

3 に答える 3

2

Zip2 つの配列を結合するために使用できます。

double result = dts.Zip(vals, (d,v) => new { d, v})
    .Where( dv => SomeCondition(dv.d))
    .Select( dv => dv.v).Average();

valsこれにより、述語が対応する値をSomeCondition返すすべての値の平均が計算されます。truedts

于 2013-04-05T14:47:25.260 に答える
0

あなたが何を探しているのか完全にはわかりませんが、チェックできるように倍精度を DateTime に変換しようとしましたか?

DateTime.FromOADate(dts[k]).DayOfWeek

多分このようなもの:

public static double aggr(double[] dts, double[] vals, double std, double edd, DayOfWeek dayOfWeek)
    {
         int stdindex = 0;
        int eddindex = dts.Length;

        List<double> newDts = new List<double>();
        List<double> newVals = new List<double>();

        // Use only values that meet criteria
        for (int k = 0; k < dts.Length; k++)
        {
            if (DateTime.FromOADate(dts[k]).DayOfWeek == dayOfWeek)
            {
                newDts.Add(dts[k]);
                newVals.Add(vals[k]);
            }
        }

        // Loop through dates that met the criteria
        for (int k = 0; k < newDts.Count; k++)
        {
            if (newDts[k] == std)
            {
                stdindex = k;
            }
            if (newDts[k] == edd)
            {
                eddindex = k;
            }
        }

        return newVals.Skip(stdindex).Take(eddindex - stdindex).Average();
    }
于 2013-04-05T14:25:05.483 に答える