[英]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
(它比较数组对象的引用,而不是数组中的值)。 不是使用数组,而是创建一个类来保存数据并定义Equals
和GetHashCode
来比较值。
老问题,但这是使用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.