从列表<t> </t>中删除重复项

时间:2014-05-14 05:33:32

标签: c# linq list generic-list

我正在编写一个音乐播放器,我有一个课程来存储歌曲。一切正常,但Linq方法Distinct().ToList()似乎不适合我的情况。我想要实现的是不能将重复的歌曲添加到列表中(我用来根据系统中的路径找到重复的歌曲)。 请仔细阅读我目前正在使用的代码并指导我。

谢谢

    using System;
using System.Linq;
using System.Collections.Generic;
using System.Text;

namespace Sample_Player
{
    public class Song
    {
        #region VARS
        public string Title
        {
            get { return title; }
            set { title = value; }
        }
        private string title;

        public string Artist
        {
            get { return artist; }
            set { artist = value; }
        }
        private string artist;

        public string Album
        {
            get { return album; }
            set { album = value; }
        }
        private string album;

        public string Genre
        {
            get { return genre; }
            set { genre = value; }
        }
        private string genre;

        public string Path
        {
            get { return path; }
            set { path = value; }
        }
        private string path;

        public int ID
        {
            get { return id; }
            set { id = value; }
        }
        private int id;

        static private List<Song> AllSongs = new List<Song>();
        #endregion VARS

        public Song()
        {

        }

        public Song(string title, string artist, string album, string genre, string path, int id)
        {
            this.Title = title;
            this.Artist = artist;
            this.Album = album;
            this.Genre = genre;
            this.Path = path;
            this.ID = id;
        }

        // What follows are DB-like functions
        static internal List<Song> GetSongs()
        {
            if (Song.AllSongs.Count == 0)
                return null;
            return Song.AllSongs.Distinct().ToList(); // returns a distinct list
        }

        static internal List<Song> GetSongsForAlbum(string title)
        {
            Dictionary<string, bool> alreadySeen = new Dictionary<string, bool>();
            List<Song> songs = new List<Song>();
            foreach (Song s in Song.GetSongs())
            {
                if (s.Album == title && !alreadySeen.ContainsKey(s.Title))
                {
                    alreadySeen[s.Title] = true;
                    songs.Add(s);
                }
            }
            return songs;
        }

        static internal List<Song> GetSongsForArtist(string title)
        {
            Dictionary<string, bool> alreadySeen = new Dictionary<string, bool>();
            List<Song> songs = new List<Song>();
            foreach (Song s in Song.GetSongs())
            {
                if (s.Artist == title && !alreadySeen.ContainsKey(s.Title))
                {
                    alreadySeen[s.Title] = true;
                    songs.Add(s);
                }
            }
            return songs;
        }

        static internal List<Song> GetSongsForGenre(string title)
        {
            Dictionary<string, bool> alreadySeen = new Dictionary<string, bool>();
            List<Song> songs = new List<Song>();
            foreach (Song s in Song.GetSongs())
            {
                if (s.Genre == title && !alreadySeen.ContainsKey(s.Title))
                {
                    alreadySeen[s.Title] = true;
                    songs.Add(s);
                }
            }
            return songs;
        }

        static internal List<Song> GetSongsForFolder(string title)
        {
            string folder;
            string fldr;
            try
            {
                System.IO.FileInfo fi = new System.IO.FileInfo(title);
                folder = fi.DirectoryName;
            }
            catch { return null; }
            Dictionary<string, bool> alreadySeen = new Dictionary<string, bool>();
            List<Song> songs = new List<Song>();
            foreach (Song s in Song.GetSongs())
            {
                try
                {
                    System.IO.FileInfo fi = new System.IO.FileInfo(s.Path);
                    fldr = fi.DirectoryName;
                }
                catch { fldr = string.Empty; }
                if (fldr == folder && !alreadySeen.ContainsKey(s.Title))
                {
                    alreadySeen[s.Title] = true;
                    songs.Add(s);
                }
            }
            return songs;
        }

        static internal List<Song> AddSongs(string title, string artist, string album, string genre, string path, int id)
        {
            Song item = new Song(title, artist, album, genre, path, id);
            Song.AllSongs.Add(item);
            return Song.AllSongs;
        }
    }
}

3 个答案:

答案 0 :(得分:4)

试试这个(假设Path属性定义唯一性)

Song.AllSongs.GroupBy(s => s.Path).Select(group => group.First()).ToList()

答案 1 :(得分:1)

使Song类实现IEquatable并覆盖EqualsGetHashCode方法。

public class Song : IEquatable<Song>
{
    bool IEquatable<Song>.Equals(Song other)

    public override int GetHashCode()
}

然后你可以调用Distinct方法。

http://msdn.microsoft.com/en-us/library/ms131187(v=vs.110).aspx

上查看更多详情

答案 2 :(得分:0)

谢谢大家,我还设法删除重复项并获得一个干净的列表。我做了什么:

static List<Song> RemoveDuplicates(IList<Song> originalList)
        {
            HashSet<string> set = new HashSet<string>();
            List<Song> cleanedList = new List<Song>(originalList.Count);

            foreach (Song obj in originalList)
            {
                if (!set.Contains(obj.path))
                {
                    set.Add(obj.path);
                    cleanedList.Add(obj);
                }
            }
            return cleanedList;
        }

并检查重复的歌曲(实际上检查一首歌是否已经在列表中。如果它在列表中,请不要将其添加到列表和播放列表中,如果该歌曲不在列表中则添加它列出和播放列表)

static internal bool isDuplicate(string path)
        {
            bool contains = Song.AllSongs.Any(s => s.path == path);
            return contains;
        }

感谢大家的建议和帮助。