简体   繁体   中英

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.

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

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM