0

I have created a list which contains a number of addresses. I want to sort the list so that they will appears numerically in order i.e.

1 Abbey Road 
2 Abbey Road
3 Abbey Road
10 Abbey Road

I've tried list.sort - which does alphabetically but therefore 10 appears before 2.

My linq is limited so I was thinking there might be a way using that or using a regex.

Any ideas?

Coder23
  • 128
  • 8
thegunner
  • 6,883
  • 30
  • 94
  • 143
  • Is this a single field, or do you store the street number in a separate field? Also, what kind of LINQ provider are you using (Linq-To-Objects, Linq-To-SQL, Linq-To-Entities)? – Tim Schmelter Nov 06 '14 at 11:56
  • It a single field just a string Containing the whole address. I'm just using/importing System.Linq – thegunner Nov 06 '14 at 12:01

3 Answers3

1

You can use Linq's OrderBy (http://msdn.microsoft.com/en-us/library/vstudio/bb549422%28v=vs.110%29.aspx) sorting:

list.OrderBy(street => street, comparer);

where street are the strings with the street name and comparer is an IComparer that sorts them the way you want. To sort string numerically you can take a look here: Sorting a List of Strings numerically (1,2,...,9,10 instead of 1,10,2)

Community
  • 1
  • 1
elnigno
  • 1,751
  • 14
  • 37
1

If you don't store the street-number in a separate field but you expect it to be in the first position, you could use this class with meaningful properties to extract all informations:

public class Address
{
    public string FullAddress { get; set; }
    public int Number { get; set; }
    public string Street { get; set; }
}

Now basically you just have to use String.Split and int.Parse, for example in this LINQ query:

List<Address> addresses = strings.Select(s => new {
    FullAddress = s.Trim(),
    Tokens = s.Trim().Split()
})
.Where(x => x.Tokens.Length > 1 && x.Tokens[0].All(Char.IsDigit))
.Select(x => new Address {
    FullAddress = x.FullAddress,
    Street = String.Join(" ", x.Tokens.Skip(1)),
    Number = int.Parse(x.Tokens[0])
})
.OrderBy(addr => addr.Number)
.ToList();

If you don't want to select this class but just your strings in the correct order, you have to change the end of the query to:

.OrderBy(addr => addr.Number)
.Select(addr => addr.FullAddress)
.ToList();

Note that the Where filters, so "invalid" addresses are skipped. If that's not desired you could use:

int number;
List<Address> addresses = strings.Select(s => new { 
    FullAddress = s.Trim(), 
    Tokens = s.Trim().Split() 
})
.Select(x => new Address{
    FullAddress = x.FullAddress,
    Street = String.Join(" ", x.Tokens.Skip(1)),
    Number = int.TryParse(x.Tokens[0], out number) ? number : int.MaxValue
})
.OrderBy(addr => addr.Number)
.ToList();
Tim Schmelter
  • 450,073
  • 74
  • 686
  • 939
0

Try this:-

var sortedList = addr.OrderBy(x => x.ID).ToList();

Fiddle.

If you are looking to sort it by Sort method, then you need to implement IComparable interface:-

public class Address : IComparable<Address>
    {
        public int ID { get; set; }
        public string Add { get; set; }

        public int CompareTo(Address other)
        {
            return this.ID.CompareTo(other.ID);
        }
    }

Then you can do:-

addr.Sort();

SortFiddle.

Rahul Singh
  • 21,585
  • 6
  • 41
  • 56