Dev
Dev

Reputation: 1007

How to compare column values of list

I have a list of rows having many columns. Say, a song is a row, and album,artist,title,year are it's columns. These are displayed in a list view. When i multi-select, say 5 songs, i need to check if the artist is the same for all 5 songs or not. The same for album,title,year.

my pseudo-code is as follows:

ListView.SelectedListViewItemCollection selectedItem = this.lvuFiles.SelectedItems;

foreach (ListViewItem itemSelected in selectedItem)
{
  // pass a list of 'title's to a method to check for equality
}

i have implemented the method which checks for equality. I just could not figure out how to store the lists (title list,album list, etc) and pass them.

EDIT:

Screenshot of List View http://i.min.us/iexmSg.png

now, i need to check the 3 Titles are matching or not. One way i thought was to add all the titles to a list and pass to the method. Do the same for artist,album. I could not get the selectedItems' value. SO, i have to maintain multiple lists for multiple properties. Is there any better way. As for the suggestions given, i tried the linq one. Says, method not defined.

Upvotes: 1

Views: 2492

Answers (2)

Dan Tao
Dan Tao

Reputation: 128307

Is there any better way.

Absolutely. The LINQ suggestion, for starters, is perfect; the only problem is that the type of the ListView.SelectedItems property does not implement IEnumerable<ListViewItem>; I'm guessing that's why it didn't work for you. You can fix this with a simple Cast<T> call:

if (listView.SelectedItems.Count > 0)
{
    var titles = from x in listView.SelectedItems.Cast<ListViewItem>()
                 select x.SubItems[titleColumn.Index].Text;

    string firstTitle = titles.First();
    bool allSameTitle = titles.All(t => t == firstTitle);
}

Now, if the real reason the LINQ suggestion didn't work for you is that you're stuck on .NET 2.0, fear not. You can still genericize this behavior. Define a method to look at each item in an IEnumerable and, based on some selector function, determine whether they all meet a given criterion. Here's an example of how you might do it:

public static bool All(IEnumerable source, Predicate<object> criterion)
{
    foreach (object item in source)
    {
        if (!criterion(item))
        {
            return false;
        }
    }

    return true;
}

Then you would call this method like this on your ListView.SelectedItems:

if (listView.SelectedItems.Count > 0)
{
    string firstTitle = listView.SelectedItems[0].SubItems[titleColumn.Index].Text;

    Predicate<object> sameTitle = delegate(object obj)
    {
        if (!(obj is ListViewItem))
        {
            return false;
        }

        return ((ListViewItem)obj).SubItems[titleColumn.Index].Text == firstTitle;
    };

    bool allSameTitle = All(listView.SelectedItems, sameTitle);
}

Upvotes: 1

justin.m.chase
justin.m.chase

Reputation: 13665

You could use the linq functional set operator 'All'.

using System.Linq;
...
var title = selectedItems.First().Column["Title"].Value;
var sameTitle = selectedItems.All(i => i.Column["Title"].Value == title);
// repeat for artist, album, year, etc.

I don't know the exact syntax of how to get a hold of the values but hopefully you can translate it. I think the key is to just note that what you're essentially asking is "are all values the same". Link is your friend for such set operations.

Upvotes: 0

Related Questions