2016-04-14 51 views
0

それぞれSomeId、AnotherId、SomeOtherId、Timestampを持つオブジェクト(以下のコードサンプルではexobject)のリストがあります。このリストには、タイムスタンプの異なるレコードが重複している可能性があります。 古いタイムスタンプでこのオブジェクトのすべての重複を削除し、最新のものを保持したいと思います。リストから重複を削除するC#の条件に基づいての条件に基づいて

サンプルオブジェクト:

SomeId AnotherId SomeOtherId Timestamp 
1   2   1    10 
1   2   1    20 
1   3   2    30 
2   3   4    40 
1   3   2    50 

私の必要なリストが

1,2,1,20 and 1,3,2,50 and 2,3,4,40. 

する必要があります私はC#で非常に粗製の実装を持ってこれを行うのですか。

for (int i = 0; i < exObject.Count - 1; i++) 
{ 
    for (int j = i + 1; j < exObject.Count - 1; j++) 
    { 
     if (exObject[i].SomeId == exObject[j].SomeId && exObject[i].AnotherId == exObject[j].AnotherId && exObject[i].SomeOtherId == exObject[j].SomeOtherId) 
     { 
      if (exObject[i].TimeStamp < exObject[j].TimeStamp) 
       exObject[i].TimeStamp = exObject[j].TimeStamp; 
      exObject.Remove(exObject[j]); 
     } 
    } 
} 

私はこれを達成するために使用することができますラムダがある場合は、これを行うかするために、よりエレガントでよりよい方法があるかどうかを知りたいです。 3つのフィールドによって

+0

あなたはexObject.Distinct()を使いたくありませんか? – Damirchi

+0

私は今、Distinctのアプローチを試みています。 – yazz

答えて

1

System.Linqのは、異なる方法があります。 IEqualityComparerを実装する必要があります。あなたのコメントに基づいてどのようにここに...

https://msdn.microsoft.com/en-us/library/bb338049(v=vs.110).aspx


編集の詳細:あなたはそれはあなたが望むものを維持する必要がありORDERBYをすれば...ここにいくつかのコードだ...

using System.Collections.Generic; 
using System.Linq; 

namespace ConsoleApplication1 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      var data = new[] 
      { 
       new SomeClass { SomeId = 1, AnotherId = 1, SomeOtherId = 1, Timestamp = 10 }, 
       new SomeClass { SomeId = 1, AnotherId = 1, SomeOtherId = 1, Timestamp = 20 }, // Duplicate 
       new SomeClass { SomeId = 1, AnotherId = 2, SomeOtherId = 2, Timestamp = 30 }, 
       new SomeClass { SomeId = 1, AnotherId = 2, SomeOtherId = 2, Timestamp = 35 }, // Duplicate 
       new SomeClass { SomeId = 2, AnotherId = 4, SomeOtherId = 4, Timestamp = 40 }, 
       new SomeClass { SomeId = 3, AnotherId = 2, SomeOtherId = 2, Timestamp = 50 }, 
       new SomeClass { SomeId = 1, AnotherId = 1, SomeOtherId = 1, Timestamp = 50 } // Duplicate 
      }; 

      var distinctList = data 
         .OrderBy(x => x.Timestamp) 
         .Distinct(new SomeClassComparer()) 
         .ToList(); 
      } 

     public class SomeClass 
     { 
      public int SomeId { get; set; } 
      public int AnotherId { get; set; } 
      public int SomeOtherId { get; set; } 
      public int Timestamp { get; set; } 
     } 

     public class SomeClassComparer : IEqualityComparer<SomeClass> 
     { 
      public bool Equals(SomeClass x, SomeClass y) 
      { 
       if (ReferenceEquals(x, y)) 
       { 
        return true; 
       } 

       //Check whether any of the compared objects is null. 
       if (ReferenceEquals(x, null) || ReferenceEquals(y, null)) 
       { 
        return false; 
       } 

       //Check whether the SomeClass's properties are equal. 
       return x.SomeId == y.SomeId && 
         x.AnotherId == y.AnotherId && 
         x.SomeOtherId == y.SomeOtherId; 
      } 

      public int GetHashCode(SomeClass someClass) 
      { 
       //Check whether the object is null 
       if (ReferenceEquals(someClass, null)) 
       { 
        return 0; 
       } 

       //Get hash code for the fields 
       var hashSomeId = someClass.SomeId.GetHashCode(); 
       var hashAnotherId = someClass.AnotherId.GetHashCode(); 
       var hashSomeOtherId = someClass.SomeOtherId.GetHashCode(); 

       //Calculate the hash code for the SomeClass. 
       return (hashSomeId^hashAnotherId)^hashSomeOtherId; 
      } 
     } 
    } 
} 
+0

これを実装しようとしましたが、どのようにタイムスタンプに条件を追加しますか?より古いタイムスタンプを持つレコードを削除するには? – yazz

+0

これは私の現在の実装と似ています。どうもありがとう。 – yazz

0

あなたができるグループと、各グループの最初のものを取る:完璧に働いている

List 
    .GroupBy(x=> new {x.prop1, x.prop2, x.prop3 }) 
    .Select(g=> g.OrderByDescending(o=> o.dateprop).First()) 
    .ToList(); 

サンプル:

static void Main(string[] args) 
{ 
    List<Foo> myList = new List<Foo>(); 
    myList.Add(new Foo(1, 2, 1, 10)); 
    myList.Add(new Foo(1, 2, 1, 20)); 
    myList.Add(new Foo(1, 3, 2, 30)); 
    myList.Add(new Foo(2, 3, 4, 40)); 
    myList.Add(new Foo(1, 3, 2, 50)); 

    // The following returns 3 results with 20, 50 and 40 timeStamps. 

    var results = myList.GroupBy(x => new { x.SomeId, x.AnotherId, x.SomeOtherId }) 
          .Select(g => g.OrderByDescending(o => o.Timestamp).First()).ToList(); 

} 
+0

最初のものがレコードの最初のオカレンスになります。しかし、最新のタイムスタンプを持つレコードではないかもしれません。すなわち、より古いタイムスタンプを有するAレコードは、後のリストに存在することができる。私はラムダに新しいです - GroupByとOrderByDescの組み合わせはありますか?コードスニペットを入力してください。 – yazz

+0

その後、日付フィールドで注文してから最初に取ることができます – user3185569

+0

更新された回答を確認してください。 – user3185569

関連する問題