1

計算用のオブジェクトのリストが必要です。

私の現在のコードは次のようになります

private class HelperClass
{
    public DateTime TheDate {get;set;}
    public TimeSpan TheDuration {get;set;}
    public bool Enabled {get;set;}
}

private TimeSpan TheMethod()
{
    // create entries for every date
    var items = new List<HelperClass>();
    foreach(DateTime d in GetAllDatesOrdered())
    {
        items.Add(new HelperClass { TheDate = d, Enabled = GetEnabled(d), });
    }

    // calculate the duration for every entry
    for (int i = 0; i < items.Count; i++)
    {
        var item = items[i];
        if (i == items.Count -1) // the last one
            item.TheDuration = DateTime.Now - item.TheDate;
        else
            item.TheDuration = items[i+1].TheDate - item.TheDate;
    }

    // calculate the total duration and return the result
    var result = TimeSpan.Zero;
    foreach(var item in items.Where(x => x.Enabled))
        result = result.Add(item.TheDuration);
    return result;
}

計算用の型(HelperClass)を紹介するだけでは、少し醜いです。私の最初のアプローチは、Tuple<DateTime, TimeSpan, bool>通常のように使用することでしたが、インスタンスの作成後にTimeSpanを変更する必要があるため、Tuple.ItemX読み取り専用であるため、Tupleを使用できません。

匿名タイプについて考えましたが、リストを初期化する方法がわかりません

var item1 = new { TheDate = DateTime.Now,
                  TheDuration = TimeSpan.Zero, Enabled = true };

var items = new List<?>(); // How to declare this ???
items.Add(item1);
4

2 に答える 2

2

あなたは次のようにLINQでそれを行うことができます:

var itemsWithoutDuration = GetAllDatesOrdered()
    .Select(d => new { TheDate = d, Enabled = GetEnabled(d) })
    .ToList();
var items = itemsWithoutDuration
    .Select((it, k) => new { TheDate = it.d, Enabled = it.Enabled, 
         TheDuration = (k == (itemsWithoutDuration.Count - 1) ? DateTime.Now : itemsWithoutDuration[k+1].TheDate) - it.TheDate })
    .ToList();

しかし、その時点で、Tupleはより読みやすく、より簡潔になります!

于 2013-01-16T07:44:03.863 に答える
2

投影法を使用することは、私にとっては前向きな方法のように見えますが、コレクションをそれ自体で「圧縮」し、1つオフセットすることで、継続時間を計算できます。その後、1つのクエリでメソッド全体を実行できます。

// Materialize the result to avoid computing possibly different sequences
var allDatesAndNow = GetDatesOrdered().Concat(new[] { DateTime.Now })
                                      .ToList();

return allDatesNow.Zip(allDatesNow.Skip(1),
                       (x, y) => new { Enabled = GetEnabled(x),
                                       Duration = y - x })
                  .Where(x => x.Enabled)
                  .Aggregate(TimeSpan.Zero, (t, pair) => t + pair.Duration);

呼び出しはZip、各日付を後続の日付とペアにし、値の各ペアを期間と有効なフラグに変換します。Where呼び出しは、無効になっているペアを除外します。呼び出しは、結果のペアからのAggregate期間を合計します。

于 2013-01-16T07:44:58.233 に答える