簡體   English   中英

選擇與列表不同 <t> 忽略一個元素

[英]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.

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