views:

218

answers:

3

Currently I am making a mini music player / organizer for myself. However, when using a list view, it sorts alphabetically, and doesn't ignore "The" and "A":

  1. A Lot Like Me
  2. Adiago For Strings
  3. Stay Crunchy
  4. The Foresaken
  5. Time to Pretend

should be:

  1. Adiago For Strings
  2. The Foresaken
  3. A Lot Like Me
  4. Stay Crunchy
  5. Time To Pretend

It's all loaded from a multi-dimensional array, and I've even tried filtering out "The" and "A" manually, and then display the real name (from a different array), but then it just sorts the displayed name (including "The" and "A")

A: 

You could do it with a custom comparison method like this:

using System;
using System.Collections.Generic;
using System.Text.RegularExpressions;

class Example
{
    static void Main()
    {
     List<String> names = new List<String>
     {
      "A Lot Like Me",
      "Adiago For Strings",
      "Stay Crunchy",
      "The Foresaken",
      "Time to Pretend"
     };

     names.Sort(smartCompare);
    }

    static Regex smartCompareExpression
     = new Regex(@"^(?:A|The)\s*",
      RegexOptions.Compiled |
      RegexOptions.CultureInvariant |
      RegexOptions.IgnoreCase);

    static Int32 smartCompare(String x, String y)
    {
     x = smartCompareExpression.Replace(x, "");
     y = smartCompareExpression.Replace(y, "");

     return x.CompareTo(y);
    }
}

The regular expression strips off any leading "A " or "The " from the strings so that they won't effect the comparison.

Andrew Hare
+4  A: 

What you could do is to create a customer comparer and set it on your ListView instance using the ListView.ListViewItemSorter property. Then, your comparer is responsible for remvoing "the" and "a" from the start of the items being compared.

When your ListView is sorted, it will use this custom comparer to sort with, but the original values including "the" and "a" will be used as display values in the ListView (ie. you do not need to modify the values you put in the ListView - the comparer just ignores the words you want it to when sorting).

adrianbanks
A: 

This LINQ approach seems to work:

string[] input = new string[] {
   "A Lot Like Me",
   "Adiago For Strings",
   "Stay Crunchy",
   "The Foresaken",
   "Time to Pretend"
};

IEnumerable<string> ordered = input.OrderBy(s =>
    s.StartsWith("A ", StringComparison.OrdinalIgnoreCase) || s.StartsWith("The ", StringComparison.OrdinalIgnoreCase) ?
    s.Substring(s.IndexOf(" ") + 1) :
    s);

foreach (var item in ordered)
{
    Console.WriteLine(item);
}

It strips away leading "a " and "the " from the comparison, but does not alter the values in the list.

Fredrik Mörk