Reputation: 4484
I've got some longitude\latitude coordinates bunched together in a string that I'd like to split into longitude\latitude pairs. Thanks to stackoverflow I've been able to come up with the some linq that will split it into a multidimensional string array. Is there a way to split the string directly into an object that accepts the longitude latitude vs a string array then create the object?
string segment = "51.54398, -0.27585;51.55175, -0.29631;51.56233, -0.30369;51.57035, -0.30856;51.58157, -0.31672;51.59233, -0.3354"
string[][] array = segment.Split(';').Select(s => s.Split(',')).ToArray();
foreach (string[] pair in array)
{
//create object here
}
Upvotes: 9
Views: 43861
Reputation: 718
Some tasks are just easier to solve the old way:
var split = segment.Split();
var coordinates = new List<Coordinate>(split.Length);
foreach(string s in split)
{
coordinates.Add(new Coordinate(s));
}
Upvotes: 1
Reputation: 392911
Here is a ‘somewhat’ nice snippet showing:
You would want to extract certain code (e.g. the number parsing) in real life.
See it live on Ideone.com.
using System;
using System.Linq;
using System.Text.RegularExpressions;
using System.Globalization;
namespace SODemo
{
class MainClass
{
private static readonly CultureInfo CInfo = CultureInfo.CreateSpecificCulture("en-US");
public static void Main (string[] args)
{
string segment = "51.54398, -0.27585;51.55175, -0.29631;51.56233, -0.30369;51.57035, -0.30856;51.58157, -0.31672;51.59233, -0.3354";
var re = new Regex(@"\s*(?<lat>[-+]?[0-9.]+),\s*(?<lon>[-+]?[0-9.]+)\s*;", RegexOptions.Compiled | RegexOptions.CultureInvariant | RegexOptions.IgnoreCase);
var locations = re.Matches(segment).Cast<Match>().Select(m => new
{
Lat = decimal.Parse(m.Groups["lat"].Value, CInfo),
Long = decimal.Parse(m.Groups["lon"].Value, CInfo),
});
foreach (var l in locations)
Console.WriteLine(l);
}
}
}
Output:
{ Lat = 51,54398, Long = -0,27585 }
{ Lat = 51,55175, Long = -0,29631 }
{ Lat = 51,56233, Long = -0,30369 }
{ Lat = 51,57035, Long = -0,30856 }
{ Lat = 51,58157, Long = -0,31672 }
Upvotes: 3
Reputation: 27282
You could do this:
public class GeoCoordinates {
public decimal Latitude { get; set; }
public decimal Longitude { get; set; }
public GeoCoordinates( string latLongPair ) {
decimal lat, lng;
var parts = latLongPair.Split( new[] { ',' } );
if( decimal.TryParse( parts[0], out lat ) &&
decimal.TryParse( parts[1], out lng ) ) {
Latitude = lat;
Longitude = lng;
} else {
// you could set some kind of "ParseFailed" or "Invalid" property here
}
}
}
Then you can create a collection of GeoCoordinate classes thusly:
var coords = segment.Split( new[] {';'} ).Select( x => new GeoCoordinates( x ) );
Upvotes: 3
Reputation: 217263
Assuming you have a Coordinate
class with a public Coordinate(double x, double y)
constructor, you can do this:
Coordinate[] result = segment
.Split(';')
.Select(s => s.Split(','))
.Select(a => new Coordinate(x: double.Parse(a[0], NumberStyles.Number),
y: double.Parse(a[1], NumberStyles.Number))
.ToArray();
or equally
var query = from item in segment.Split(';')
let parts = item.Split(',')
let x = double.Parse(parts[0], NumberStyles.Number)
let y = double.Parse(parts[1], NumberStyles.Number)
select new Coordinate(x, y);
Coordinate[] result = query.ToArray();
Upvotes: 6
Reputation: 4296
I might add a bit more. Thanks to dtb for the start, upvoted. If you break your parsing function out, you can more cleanly handle error conditions, such as wrong number of elements in your array, or things that don't parse to a decimal.
Coordinate[] result = segment
.Split(';')
.Select(s => s.Split(','))
.Select(BuildCoordinate)
.ToArray();
Coordrinate BuildCoordinate(string[] coords)
{
if(coords.Length != 2)
return null;
return new Coordinate(double.Parse(a[0].Trim(), double.Parse(a[1]);
}
Upvotes: 1
Reputation: 6356
Is it a necessity that you use LINQ? You can do it all with standard string splitting functionality:
string[] pairsOfCoords = segment.Split(';');
List<CoordsObject> listOfCoords = new List<CoordsObject>();
foreach (string str in pairsOfCoords)
{
string[] coords = str.Split(',');
CoordsObject obj = new CoordsObject(coords[0], coords[1]);
listOfCoords.Add(obj);
}
Upvotes: 2
Reputation: 421978
You are close. Something like this might help:
var pairSequence = segment.Split(';')
.Select(s => s.Split(','))
.Select(a => new { Lat = double.Parse(a[0]), Long = double.Parse(a[1]) });
Upvotes: 24