[英]Select distinct from List<t> ignoring one element
我有一個自定義數據類型列表,簡化示例( myMovies
):
public class Movie
{
public Int32 TVIndex;
public string MovieName;
public string MovieRating;
public string MovieRuntime;
public List<Actor> MovieActors;
public List<MovieArt> MovieImages;
}
public class Actor
{
public string ActorName;
public string ActorRole;
}
public class MovieArt
{
public string ImagePath;
}
List<Movie> myMovies = new List<Movie>();
現在我試圖從myMovies
刪除所有重復但忽略TVIndex
。
我試過看
List<Movie> myDistinctMovies = myMovies.Distinct().ToList();
但無法弄清楚如何忽略TvIndex
。 這可能嗎?
基於@Grundy的回答,包括實施:
public class MovieEqualityComparer : IEqualityComparer<Movie>
{
public bool Equals(Movie x, Movie y)
{
if ( x == null )
return y == null;
if ( y == null )
return x == null;
if ( object.ReferenceEquals(x, y) )
return true;
if ( !string.Equals(x.MovieName, y.MovieName) )
return false;
if ( !string.Equals(x.MovieRating, y.MovieRating) )
return false;
if ( !string.Equals(x.MovieRuntime, y.MovieRuntime) )
return false;
if ( !Enumerable.SequenceEqual(x.MovieActors, y.MovieActors) )
return false;
if ( !Enumerable.SequenceEqual(x.MovieImages, y.MovieImages) )
return false;
return true;
}
public int GetHashCode(Movie obj)
{
if ( obj == null )
throw new ArgumentNullException();
unchecked
{
int hash = 17;
hash = hash * 31 + ((obj.MovieName == null) ? 0 : obj.MovieName.GetHashCode());
hash = hash * 31 + ((obj.MovieRating == null) ? 0 : obj.MovieRating.GetHashCode());
hash = hash * 31 + ((obj.MovieRuntime == null) ? 0 : obj.MovieRuntime.GetHashCode());
if ( obj.MovieActors != null )
{
foreach ( var actor in obj.MovieActors )
hash = hash * 31 + ((actor == null) ? 0 : actor.GetHashCode());
}
if ( obj.MovieImages != null )
{
foreach ( var image in obj.MovieImages )
hash = hash * 31 + ((image == null) ? 0 : image.GetHashCode());
}
return hash;
}
}
}
用法是一樣的:
List<Movie> myMovies = new List<Movie>
{
// ...
};
List<Movie> myDistinctMovies = myMovies.Distinct(new MovieEqualityComparer()).ToList();
編輯
正如@Tim所指出的,如果你想通過除引用相等之外的任何東西進行比較,你必須為你的其他自定義類型做一些非常類似的事情。
public class Actor : IEquatable<Actor>
{
public string ActorName;
public string ActorRole;
public override bool Equals(object obj)
{
return this.Equals(obj as Actor);
}
public bool Equals(Actor other)
{
if ( other == null )
return false;
if ( object.ReferenceEquals(this, other) )
return true;
if ( !string.Equals(this.ActorName, other.ActorName) )
return false;
if ( !string.Equals(this.ActorRole, other.ActorRole) )
return false;
return true;
}
public override int GetHashCode()
{
unchecked
{
int hash = 17;
hash = hash * 31 + ((ActorName == null) ? 0 : ActorName.GetHashCode());
hash = hash * 31 + ((ActorRole == null) ? 0 : ActorRole.GetHashCode());
return hash;
}
}
}
public class MovieArt : IEquatable<MovieArt>
{
public string ImagePath;
public override bool Equals(object obj)
{
return this.Equals(obj as MovieArt);
}
public bool Equals(MovieArt other)
{
if ( other == null )
return false;
if ( object.ReferenceEquals(this, other) )
return true;
if ( !string.Equals(this.ImagePath, other.ImagePath) )
return false;
return true;
}
public override int GetHashCode()
{
unchecked
{
int hash = 17;
hash = hash * 31 + ((ImagePath == null) ? 0 : ImagePath.GetHashCode());
return hash;
}
}
}
你可以使用Distinct with EqualityComparer這樣的東西
public class MoviesEqualityComparer : IEqualityComparer<Movie>
{
public bool Equals(Movie x, Movie y)
{
return ..../* check all needed fields */
}
public int GetHashCode(Movie obj)
{
return .... /* get hashcode for movie objec*/
}
}
並使用它
List<Movie> myDistinctMovies = myMovies.Distinct(new MoviesEqualityComparer()).ToList();
你可以使用LINQ查詢可能...
List<Movie> myDistinctMovies = (myMovies .GroupBy(p =>p.MovieName,
p =>p.MovieRating,p=>p.MovieRuntime)
.Select(g => g.First())
.ToList());
謝謝..
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.