1

統合する必要がある 2 つのリストがあります。リスト 1 には日付のみが含まれ、リスト 2 には時間要素も含まれる場合があります。

var List1 = new[] { 
  new ListType{ val = new DateTime(2012, 1, 1)}, 
  new ListType{ val = new DateTime(2012, 1, 2)} 
};

List2 = new[] { new ListType{ val = new DateTime(2012, 1, 1, 5, 0, 0)} };

FinalList = new[] { 
  new ListType{ val = new DateTime(2012, 1, 1, 5, 0, 0)}, 
  new ListType{ val = new DateTime(2012, 1, 2)} 
};

私がこれについて行っている方法は次のとおりです。

foreach (var l in List1) {
  var match = List2.FirstOrDefault(q => q.val.Date == l.val);
  if (match == null) continue;
  l.val = match.val;
}

List1 を反復処理し、FirstOrDefault を使用してから val を再割り当てするよりも良い方法はありますか? それは機能するので、Linq がよりエレガントな方法を持っている場合、これは単なる好奇心です (つまり、明らかな何かが欠けています)。

ありがとう

4

2 に答える 2

0

Enumerable.Unionカスタムで使用できますIEqualityComparer<ListType>

class ListType
{
    public DateTime val { get; set; }

    public class DateComparer : IEqualityComparer<ListType>
    {
        public bool Equals(ListType x, ListType y)
        {
            if (ReferenceEquals(x, y))
                return true;
            else if (x == null || y == null)
                return false;
            return x.val.Date == y.val.Date;
        }

        public int GetHashCode(ListType obj)
        {
            return obj.val.Date.GetHashCode();
        }
    }
}

その後 ...

var finalList = List2.Union(List1, new ListType.DateComparer());
于 2012-11-20T12:52:45.383 に答える
0

ループを取り除くつもりはありませんが、効率化のために、日付を最初の一致時刻にマッピングする辞書を作成します。

var dateToTime = List2
    .GroupBy(d => d.Date)
    .ToDictionary(g => g.Key, g => g.First());
foreach (var l in List1)
{
    DateTime match;
    if (dateToTime.TryGetValue(l.val, out match))
        l.val = match.val;
}

LINQ は、アイテムを更新するのではなく、アイテムをクエリするために作成されています。アイテムを更新する必要がある場合は、foreachループなどの非 LINQ を使用してください。とはいえ、最初のリストの項目から新しいリストを生成したい場合、次のコードは同等です。

var newList = List1.Select(l => new ListType { val = 
    dateToTime.ContainsKey(l.val) ? dateToTime[l.val] : l.val }).ToList();
于 2012-11-20T12:53:13.337 に答える