23

タプルのリストから重複を見つけて削除する必要があります。基本的に、私の構造はそのように作られています:

List<Tuple<string, string>> myList = new List<Tuple<string, string>>();

****

private void FillStructure()
{
     myList.Add(Tuple.Create<string, string>("A", "B"));
     myList.Add(Tuple.Create<string, string>("A", "C"));
     myList.Add(Tuple.Create<string, string>("C", "B"));
     myList.Add(Tuple.Create<string, string>("C", "B"));    // Duplicate
     myList.Add(Tuple.Create<string, string>("A", "D"));

     FindAndRemoveDuplicates(myList);
}

private void FindAndRemoveDuplicates(List<Tuple<string, string>> myList)
{
        // how can I perform this ?
}

同じキーでも異なる値を持つことができるため、辞書を使用できません! 前もって感謝します

4

4 に答える 4

6

この目的で HashSet を使用できます ( http://msdn.microsoft.com/en-us/library/bb359438.aspx )

class SameTuplesComparer<T1, T2> : EqualityComparer<Tuple<T1, T2>> 
{
   public override bool Equals(Tuple<T1, T2> t1, Tuple<T1, T2> t2)
   {
      return t1.Item1.Equals(t2.Item1) && t1.Item2.Equals(t2.Item2)
   }


   public override int GetHashCode(Tuple<T1, T2> t)
   {
     return base.GetHashCode();
   }
}

したがって、独自の比較子を作成する場合は、文字列を少し異なる方法で比較できます (例として、大文字と小文字を区別しません)。

class SameStringTuplesComparer: EqualityComparer<Tuple<string, string>> 
{
   public override bool Equals(Tuple<string, string> t1, Tuple<string, string> t2)
   {
      return t1.Item1.Equals(t2.Item1, StringComparison.CurrentCultureIgnoreCase) && t1.Item2.Equals(t2.Item2, StringComparison.CurrentCultureIgnoreCase)
   }


   public override int GetHashCode(Tuple<string, string> t)
   {
     return base.GetHashCode();
   }
}

次にコードで:

var hashSet = new HashSet<Tuple<string, string>>(list, new SameTuplesComparer());

または、独自の比較子なしで:

var hashSet = HashSet<Tuple<string, string>>(list);

要素を hashSet に追加すると、すべての要素が一意になります。要素の追加が完了したら、再度リストに変換できます。

var uniquedList = hashSet.ToList();

または単に使用するlist.Distinct().ToList()

于 2013-06-24T12:50:08.807 に答える
0

リストを適切に修正するソリューションが必要な場合は、 a を使用できますHashSet<T>(または、古いフレームワークの場合は a を使用Dictionary<Tuple<string, string>, object>して値を無視します)。

var existing = new HashSet<Tuple<string, string>>();

for (int i = myList.Count - 1; i >= 0; i--)
{
    if (existing.Contains(myList[i]))
    {
        myList.RemoveAt(i);
    }
    else
    {
        existing.Add(myList[i]);
    }
}

イテレータを使用せずに逆方向にカウントします (そうしないと、反復中にリストを修正するとエラーが発生します)。

HashSet<T>必要に応じて等値をオーバーライドするためのオーバーロードもあります。

個人的には、読みやすさのためにdasblinkenlight の回答に行きます。

于 2013-06-24T12:49:53.047 に答える
0

使用distinct()方法:

myList.Distinct().ToList();
于 2013-06-24T12:47:00.530 に答える