C# Array sort question

Associate
Joined
30 Mar 2004
Posts
1,148
Location
West Wing
Hi,

I have an array of strings like this:

List<string> myList = new List<string>();
myList.add("Samuel, 01/09/2014");
myList.add("David, 15/08/2014");
myList.add("Alan, 19/08/2014");
myList.add("Ellen, 03/07/2014");
myList.add("Alan, 20/08/2014");

What i want to do is sort the array alphabetically by the name in the first part of the string without losing the associated date information.

Hope that makes sense, not sure if im going about this in the best way. Should i be using a different type of array? Or maybe create 2 separate arrays?

Appreciate any advice :)
 
in that example you just need to call myList.Sort(); to sort it a-z. It works because you are storing all the information inside one string.

A more OO way would be to make up an object with separate parameters like this.

Code:
List<Person> people = new List<Person>();
people.Add(new Person("Samuel", new DateTime(2014, 9, 1)));
people.Add(new Person("David", new DateTime(2014, 8, 15)));
people.Add(new Person("Alan", new DateTime(2014, 8, 19)));
people.Add(new Person("Ellen", new DateTime(2014, 7, 3)));
people.Add(new Person("Alan", new DateTime(2014, 8, 20)));

people.Sort((x, y) => x.Name.CompareTo(y.Name));

public class Person
{
	public string Name {get;set;}
	public DateTime DOB {get;set;}
	
	public Person(string name, DateTime dob)
	{
		Name = name;
		DOB = dob;
	}
}
 
in that example you just need to call myList.Sort(); to sort it a-z. It works because you are storing all the information inside one string.

A more OO way would be to make up an object with separate parameters like this.

Code:
List<Person> people = new List<Person>();
people.Add(new Person("Samuel", new DateTime(2014, 9, 1)));
people.Add(new Person("David", new DateTime(2014, 8, 15)));
people.Add(new Person("Alan", new DateTime(2014, 8, 19)));
people.Add(new Person("Ellen", new DateTime(2014, 7, 3)));
people.Add(new Person("Alan", new DateTime(2014, 8, 20)));

people.Sort((x, y) => x.Name.CompareTo(y.Name));

public class Person
{
	public string Name {get;set;}
	public DateTime DOB {get;set;}
	
	public Person(string name, DateTime dob)
	{
		Name = name;
		DOB = dob;
	}
}

Basically this, if you continue with the just having it as one string and doing .sort() you will get some oddities if there are people with the same name as the DOB will be sorted alphabetically not numerically.
 
Thanks, i didn't think of using the sort function.

Another question, how do I remove duplicates from the array? You can see in my first example there are 2 Alans.
 
Thanks, i didn't think of using the sort function.

Another question, how do I remove duplicates from the array? You can see in my first example there are 2 Alans.

Do you want to remove duplicates even if the DOB is not the same?
If you want to remove 2 items that are the same

myList = myList.ToDistinct().ToList() should do that.
 
I want to remove items that have the same name only. I.e. remove the second Alan, even though the date is different to the first Alan.
 
Thanks, i didn't think of using the sort function.

Another question, how do I remove duplicates from the array? You can see in my first example there are 2 Alans.

You don't have any duplicates in your list, because the strings are not the same (the two Alans have different dates of birth). You really do NOT want to be storing names and dates of birth as a single string, in the way you describe in your original post, if your intention is to perform any kind of action (sorting, de-duplicating, etc.) on the names and dates separately.

Also you're not using an Array, you're using a List - these are two different data structures, and will fundamentally affect the way you do everything you're asking about.
 
Also you're not using an Array, you're using a List - these are two different data structures, and will fundamentally affect the way you do everything you're asking about.

yep, using the List collection types is much nicer in c# than using arrays, they provide more features and are easier to work with. Once you've learnt all the basics then you can start to pick specific collection types where it makes sense to improve performance etc.

There's a cool program you can download to help learn all the object types

http://www.linqpad.net/

Change the top language dropdown to C# program and copy this in

Code:
void Main()
{
	List<Person> people = new List<Person>();
	people.Add(new Person("Samuel", new DateTime(2014, 9, 1)));
	people.Add(new Person("David", new DateTime(2014, 8, 15)));
	people.Add(new Person("Alan", new DateTime(2014, 8, 19)));
	people.Add(new Person("Ellen", new DateTime(2014, 7, 3)));
	people.Add(new Person("Alan", new DateTime(2014, 8, 20)));
	
	people = people.Distinct().ToList();
	
	people.Sort((x, y) => x.Name.CompareTo(y.Name));
	
	people.Dump();
}

public class Person
{
	public string Name {get;set;}
	public DateTime DOB {get;set;}
	
	public Person(string name, DateTime dob)
	{
		Name = name;
		DOB = dob;
	}
}

and you'll end up with this in the result window

13zbvjp.jpg
 
Last edited:
You can overload the Disctinct() method if you want to, as well.

Code:
people.Distinct(p => p.Name)

edit: Ugh. This what I get for not actually checking before posting:

The above overload doesn't exist, which is quite a surprise. You'd need to provide an implementation of IEqualityComparer<Person> instead of the lambda like that in my example above.
 
Last edited:
You can overload the Disctinct() method if you want to, as well.

Code:
people.Distinct(p => p.Name)

edit: Ugh. This what I get for not actually checking before posting:

The above overload doesn't exist, which is quite a surprise. You'd need to provide an implementation of IEqualityComparer<Person> instead of the lambda like that in my example above.
I was going to post the exact same thing and thought Id double check
Found this though to do it in 1 line
myList.GroupBy(p => p.Name).Select(grp => grp.First());
 
It's really annoying - inexplicable - that Distinct() can't take the same lambda expression as most other similar LINQ operations.

MoreLINQ adds method DistinctBy() which does allow it:
https://www.nuget.org/packages/morelinq/1.1.0

There's also the Interactive Extensions which provide a similar thing.

It was written by the Reactive Extensions team at Microsoft and basically adds various extension methods to Linq to objects to give the same methods over enumerables as Rx provides for observables.
 
Back
Top Bottom