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