Question

I am coding a music player, and I have a class to store songs. Everything works fine, but the Linq method Distinct().ToList() seems not working for my case. What I wanted to implement that a duplicate song must not be added to list (I use to find duplicate songs based on there path in the system). Kindly review my code which I am using currently and guide me.

Thank you

    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;
        }
    }
}
Was it helpful?

Solution

Try this (assuming Path property defines uniqueness)

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

OTHER TIPS

Make Song class implement IEquatable and override Equals and GetHashCode methods.

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

    public override int GetHashCode()
}

Then you can just call Distinct method.

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

Thanks everyone I also managed to remove duplicates and get a clean list. What I done:

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;
        }

And to check for duplicate songs (Actually to check if a song is already in List or not. If it's in List, do not add it to list and playlist, if the song is not in list then add it to list and playlist)

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

Thank you everyone for suggestions and help.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top