2012-04-09 106 views
8

我有一些經度\緯度座標聚集在一個字符串中,我想分成經度\緯度對。感謝stackoverflow我已經能夠拿出一些linq,將它分割成多維的字符串數組。有沒有辦法將字符串直接分割成一個對象,該對象接受經度緯度vs字符串數組,然後創建對象?有沒有更好的方法來使用LINQ來分割這個字符串?

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 
} 
+1

有(幾乎?)從來沒有使用LINQ to分割字符串的好方法。也就是說,System.Text.RegularExpressions就是你想要的 – sehe 2012-04-09 21:52:33

+1

什麼是你的字符串末尾的「-0.3354」,「London:484」? – 2012-04-09 21:54:29

+2

@sehe:對這樣一個簡單的任務使用正則表達式是矯枉過正的。你知道你輸入的格式是不變的,而且很容易通過分割來分析*應該*使用split而不是正則表達式。 – 2012-04-09 21:55:45

回答

20

你就近了。像這樣的東西可能會有所幫助:

var pairSequence = segment.Split(';') 
     .Select(s => s.Split(',')) 
     .Select(a => new { Lat = double.Parse(a[0]), Long = double.Parse(a[1]) }); 
+0

@Alex當然,取決於你實際需要的類型。你明白了。 – 2012-04-09 21:56:35

+0

該死的。正在寫幾乎相同的東西。榮譽。 – 2012-04-09 21:57:03

+0

完美,謝謝!只是忘了新的{}部分。 – NullReference 2012-04-09 22:02:41

6

假設你有一個Coordinate類與public Coordinate(double x, double y)構造函數,你可以這樣做:

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

或同樣

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

它是一個必要的是你使用LINQ?您可以使用標準字符串拆分功能完成所有操作:

​​
+1

是的,但看看linq有多清潔。 :) – 2012-04-09 21:56:40

+1

@RobertP:嗯,我想這是主觀的。這看起來很簡單,對我來說很乾淨。 – 2012-04-09 21:57:55

1

我可能會添加更多。感謝dtb的啓動,upvoted。如果你打破了你的解析函數,你可以更乾淨地處理錯誤條件,比如數組元素數量錯誤,或者不能解析爲小數。

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]); 
} 
3

你可以這樣做:

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 
    } 
    } 
} 

然後你就可以正是如此創建會有地理座標類的集合:

var coords = segment.Split(new[] {';'}).Select(x => new GeoCoordinates(x)); 
+0

你打敗了我! :) – SouthShoreAK 2012-04-09 22:02:23

+0

heh ... StackOverflow可以相當比賽,不是嗎? – 2012-04-09 22:07:50

3

這裏是一個 '有點' 好片斷顯示:

  • precompiled regexen
  • LINQ匿名類型的投影
  • 文化感知(正確)數字分析和打印

你會想提取某些代碼(例如數字解析)在現實生活中。

查看一下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); 
     } 
    } 
} 

輸出:

{ 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 } 
相關問題