Search code examples
c#wpfstringspliticollection

How to iterate through comma-separated string properties, split the strings and create an ICollection from all distinct values


I have a class “Movie_Class” related to data coming from an xml file. To read the xml file I use a class “StoreDbDataSet”:

public class StoreDbDataSet
{
    public DataTable GetMovies()
    {
        return ReadDataSet().Tables[0];
    }


    internal static DataSet ReadDataSet()
    {
        DataSet ds = new DataSet();
        ds.ReadXml("Peter_Movie_Database.xml");
        return ds;
    }

}

The “Movie_Class”:

public class Movie_Class : INotifyPropertyChanged
{

    private string mediaLabel;
    public string MediaLabel
    {
        get { return mediaLabel; }
        set
        {
            mediaLabel = value;
            OnPropertyChanged(new PropertyChangedEventArgs("MediaLabel"));
        }
    }

    private string year;
    public string Year
    {
        get { return year; }
        set
        {
            year = value;
            OnPropertyChanged(new PropertyChangedEventArgs("Year"));
        }
    }

    private string originalTitle;
    public string OriginalTitle
    {
        get { return originalTitle; }
        set
        {
            originalTitle = value;
            OnPropertyChanged(new PropertyChangedEventArgs("OriginalTitle"));
        }
    }

    private string director;
    public string Director
    {
        get { return director; }
        set
        {
            director = value;
            OnPropertyChanged(new PropertyChangedEventArgs("Director"));
        }
    }

    private string category;
    public string Category
    {
        get { return category; }
        set
        {
            category = value;
            OnPropertyChanged(new PropertyChangedEventArgs("Category"));
        }
    }


    public Movie_Class(string originalTitle, string year,
        string director, string mediaLabel, string category)
    {
        OriginalTitle = originalTitle;
        Year = year;
        Director = director;
        MediaLabel = mediaLabel;
        Category = category;
    }

    public event PropertyChangedEventHandler PropertyChanged;
    public void OnPropertyChanged(PropertyChangedEventArgs e)
    {
        if (PropertyChanged != null)
            PropertyChanged(this, e);
    }

}

I created an Icollection of all the distinct “year” properties. See GetDistinctYear() in the code below. I can then use this Icollection as an ItemsSource for a combobox in wpf. This works fine. But now I want to do the same for a property called “Category”. The problem is that this is a comma-separated string. (For example: Drama, Thriller, War) I don’t know how to iterate through all the “Category” properties, split the strings and make an Icollection containing all distinct categories.

public class StoreDb
{

    public ICollection<Movie_Class> GetMovies()
    {
        DataSet ds = StoreDbDataSet.ReadDataSet();

        ObservableCollection<Movie_Class> movies = new ObservableCollection<Movie_Class>();
        foreach (DataRow productRow in ds.Tables["Movie"].Rows)
        {
            movies.Add(new Movie_Class((string)productRow["OriginalTitle"],
                (string)productRow["Year"], (string)productRow["Director"],
                (string)productRow["MediaLabel"], (string)productRow["Category"]));
        }
        return movies;
    }

    public ICollection<Movie_Class> GetDistinctYear()
    {

        ICollection<Movie_Class> movies = GetMovies();


        IEnumerable<Movie_Class> matches = from movie in movies
                                           group movie by movie.Year into grps
                                           select grps.First();


        return new ObservableCollection<Movie_Class>(matches.ToList());
    }

    public ICollection<Movie_Class> GetDistinctCategory()
    {


    }


}

The code from my .cs file of the mainwindow.xaml:

 public partial class MainWindow : Window
{

    private ICollection<Movie_Class> moviesByYear;
    private ICollection<Movie_Class> moviesByCategory;
    private ICollection<Movie_Class> AllMovies;

    public MainWindow()
    {
        InitializeComponent();

        AllMovies = App.StoreDb.GetMovies();

        moviesByYear = App.StoreDb.GetDistinctYear();
        ComboBox_Year.ItemsSource = moviesByYear;

        moviesByCategory = App.StoreDb.GetDistinctCategory();
        ComboBox_Category.ItemsSource = moviesByCategory; 

        ICollectionView view = CollectionViewSource.GetDefaultView(ComboBox_Year.ItemsSource);     
        view.SortDescriptions.Add(new SortDescription("Year", ListSortDirection.Ascending));   
    }

Solution

  • Try this:

    public ICollection<string> GetDistinctCategory()
    {
        ICollection<Movie_Class> movies = GetMovies();
    
        return movies.SelectMany(x => x.Category.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
            .Select(x => x.Trim())
            .Distinct()
            .ToList();
    }