簡體   English   中英

從字符串數組中刪除重復項

[英]Removing duplicates from string array

我是C#的新手,看過很多帖子,但我仍然很困惑。

我有一個數組列表:

List<Array> moves = new List<Array>();

我正在使用以下內容添加移動:

string[] newmove = { piece, axis.ToString(), direction.ToString() };
moves.Add(newmove);

現在我希望使用以下內容刪除重復項:

moves = moves.Distinct();

然而,這不是讓我這樣做的。 我收到此錯誤:

無法將類型'System.Collections.Generic.IEnumerable'隱式轉換為'System.Collections.Generic.List'。 存在顯式轉換(您是否錯過了演員?)

請幫忙? 我會非常感激的。

史蒂夫

你需要在.Distinct方法之后調用.ToList() ,因為它返回IEnumerable<T> 我還建議您使用強類型List<string[]>而不是List<Array>

List<string[]> moves = new List<string[]>();
string[] newmove = { piece, axis.ToString(), direction.ToString() };
moves.Add(newmove);
moves.Add(newmove);

moves = moves.Distinct().ToList();
// At this stage moves.Count = 1

您的代碼有兩個錯誤。 第一個是對ToList的缺失調用,正如已經指出的那樣。 第二是微妙的。 Unique按標識比較對象,但重復的列表項具有不同的數組實例。

該問題有多種解決方案。

  • moves.Distinct().ToList()使用自定義相等比較器。 無需進一步更改。

    示例實施:

     class ArrayEqualityComparer<T> : EqualityComparer<T> { public override bool Equals(T[] x, T[] y) { if ( x == null ) return y == null; else if ( y == null ) return false; return x.SequenceEquals(y); } public override int GetHashCode(T[] obj) { if ( obj == null) return 0; return obj.Aggregate(0, (hash, x) => hash ^ x.GetHashCode()); } } 

    過濾獨特的項目:

     moves = moves.Distinct(new ArrayEqualityComparer<string>()).ToList(); 
  • 使用Tuple <string,string,string>而不是string[] 元組提供內置的結構平等和比較。 由於長類型名稱,此變體可能會使代碼混亂。

    實例:

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

    添加新動作:

     Tuple<string, string, string> newmove = Tuple.Create(piece, axis.ToString(), direction.ToString()); moves.Add(newmove); 

    過濾獨特的項目:

     moves = moves.Distinct().ToList(); 
  • 使用自定義類來保存三個值。 我實際上推薦這個變種,因為它使你處理動作的所有代碼更具可讀性。

    示例實施:

     class Move { public Move(string piece, string axis, string direction) { Piece = piece; Axis = axis; Direction = direction; } string Piece { get; private set; } string Axis { get; private set; } string Direction { get; private set; } public override Equals(object obj) { Move other = obj as Move; if ( other != null ) return Piece == other.Piece && Axis == other.Axis && Direction == other.Direction; return false; } public override GetHashCode() { return Piece.GetHashCode() ^ Axis.GetHashCode() ^ Direction.GetHashCode(); } // TODO: override ToString() as well } 

    實例:

     List<Move> moves = new List<Move>(); 

    添加新動作:

     Move newmove = new Move(piece, axis.ToString(), direction.ToString()); moves.Add(newmove); 

    過濾獨特的項目:

     moves = moves.Distinct().ToList(); 

編譯器錯誤是因為您需要將結果轉換為列表:

moves = moves.Distinct().ToList();

但是它可能無法正常工作,因為數組沒有以您希望的方式定義的Equals (它比較數組對象的引用,而不是數組中的值)。 不是使用數組,而是創建一個類來保存數據並定義EqualsGetHashCode來比較值。

老問題,但這是使用O(1)額外空間的O(n)解決方案:

public static void RemoveDuplicates(string[] array)
    {
        int c = 0;
        int i = -1;

        for (int n = 1; n < array.Length; n++)
        {
            if (array[c] == array[n])
            {
                if (i == -1)
                {
                    i = n;
                }
            }
            else
            {
                if (i == -1)
                {
                    c++;
                }
                else
                {
                    array[i] = array[n];
                    c++;
                    i++;
                }
            }
        }
    }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM