17

Could anyone please teach me how to insert item into list in alphabetical order in C#?

So every time I add to the list I want to add an item alpabetically, the list could become quite large in theory.

Sample Code:

Public Class Person
{
     public string Name { get; set; }
     public string Age { get; set; }
}

Public Class Storage
{
    private List<Person> people;

    public Storage
    {
        people = new List<Person>();
    }


    public void addToList(person Person)
    {
        int insertIndex = movies.findindex(
            delegate(Movie movie) 
            {
              return //Stuck here, or Completely off Track.

            }
        people.insert(insertIndex, newPerson);
    }

}
Kirill Polishchuk
  • 54,804
  • 11
  • 122
  • 125
Jaybeecave
  • 827
  • 2
  • 8
  • 17
  • 1
    Here in this Stackoverflow : http://stackoverflow.com/questions/188141/c-sharp-list-orderby-alphabetical-order – Đức Bùi Nov 01 '12 at 04:22
  • 3
    @John3136 Inserting in the appropriate position is not the same as re-sorting the list after each insert. – Kirk Broadhurst Nov 01 '12 at 04:33
  • Use a specialized collection - e.g. sortedlist. List.Insert isn't an efficient solution in terms of LOC, bugs, cpu, memory, programmer time etc. – NPSF3000 Nov 01 '12 at 04:41
  • 2
    Kirk - I don't see where I suggested that it was. My intent was to find one of the existing sorted collection classes rather than finding out how to sort a collection. – John3136 Nov 01 '12 at 05:01

5 Answers5

12

Define a comparer implemeting IComparer<T> Interface:

public class PersonComparer : IComparer<Person>
{
    public int Compare(Person x, Person y)
    {
        return x.Name.CompareTo(y.Name);
    }
}

And use SortedSet<T> Class then:

        SortedSet<Person> list = new SortedSet<Person>(new PersonComparer());
        list.Add(new Person { Name = "aby", Age = "1" });
        list.Add(new Person { Name = "aab", Age = "2" });
        foreach (Person p in list)
            Console.WriteLine(p.Name);

If you are limited to usinf .NetFramework3.5, you could use SortedList<TKey, TValue> Class then:

SortedList<string, Person> list = 
          new SortedList<string, Person> (StringComparer.CurrentCulture);
Person person = new Person { Name = "aby", Age = "1" };
list.Add(person.Name, person);
person = new Person { Name = "aab", Age = "2" };
list.Add(person.Name, person);

foreach (Person p in list.Values)
    Console.WriteLine(p.Name);

Espesially read the Remarks section in the MSDN artcile, comparing this class and SortedDictionary<TKey, TValue> Class

horgh
  • 17,918
  • 22
  • 68
  • 123
11

Old thread, but the answers in this thread IMO are ignoring OP's actual question. The question is straightforward - how do you insert into a list in sorted order. That's not the same as "just use a SortedSet / SortedList". There will be different characteristics and implications based on using the below vs. using a SortedList.

SortedSet and SortedList are both based off of Dictionary, and won't allow you to add two items with the same key AFAIK.

So how do you account for a list such as, { a, b, c, c, d }?

Here is the correct way to insert into an ordered list so that the items remain ordered:

var binarySearchIndex = list.BinarySearch(item, itemComparer);
//The value will be a negative integer if the list already 
//contains an item equal to the one searched for above
if (binarySearchIndex < 0)
{
    list.Insert(~binarySearchIndex, item);
}
else
{
    list.Insert(binarySearchIndex, item);
}

Answer via this great article from 2010: https://debugmode.net/2010/09/18/inserting-element-in-sorted-generic-list-list-using-binary-search/

Aen
  • 7,433
  • 3
  • 20
  • 21
5

If you're absolutely looking to use a list, try this:

int loc;
for(loc = 0; loc < people.Count && people[loc].Name.CompareTo(personToInsert.Name) < 0; loc++);
people.Insert(loc, personToInsert);

You can replace people[loc].Name.CompareTo(personToInsert.Name) < 0 with whatever condition you're testing for - and you can change the sign to make it descending instead of ascending. Like people[loc].Age < personToInsert.Age for example would sort by age.

Sessamekesh
  • 420
  • 1
  • 6
  • 10
  • While this is not the most efficient sorted insertion for most lists, for very small ones (eg : less than 10 elements), this is probably faster than performing a binary search. Personally, I would have use a `while` instead of a `for` (but that does not matter). – tigrou Jan 22 '15 at 16:17
  • This worked fine for me thanks. I just needed an easy lightweight way to insert a new item into the correct position in a drop down list bound to an observable collection. – Richard Moore Nov 11 '20 at 18:17
2

Take a look at SortedSet<T> class. Simply use it instead of List<T>.

Kirill Polishchuk
  • 54,804
  • 11
  • 122
  • 125
2

SortedList is what you need.Create a StringComparer object and pass it to the constructor of the sortedlist.The elements are automatically sorted as new items are inserted.

StringComparer stringComp = StringComparer.CurrentCulture;
SortedList sl = new SortedList(stringComp);
sl.Add("B", "SECOND");
sl.Add("A", "FIRST");
sl.Add("C", "THIRD");
Prabhu Murthy
  • 9,031
  • 5
  • 29
  • 36