2012-04-09 27 views
8

Tôi có một số tọa độ vĩ độ kinh độ được nhóm lại với nhau trong một chuỗi mà tôi muốn chia thành các cặp kinh độ \ vĩ độ. Nhờ stackoverflow tôi đã có thể đến với một số LINQ mà sẽ chia nó thành một mảng chuỗi đa chiều. Có cách nào để tách chuỗi trực tiếp thành một đối tượng chấp nhận kinh độ vĩ độ so với một mảng chuỗi sau đó tạo đối tượng?Có cách nào tốt hơn để tách chuỗi này bằng LINQ không?

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

Có (gần?) Bao giờ là một cách tốt để chia một chuỗi sử dụng LINQ. Điều đó nói rằng, System.Text.RegularExpressions là những gì bạn muốn – sehe

+1

Đó là gì '-0.3354", "London: 484" 'ở cuối chuỗi của bạn? –

+2

@sehe: Sử dụng cụm từ thông dụng cho một nhiệm vụ tầm thường như vậy là quá mức cần thiết. bạn biết rằng định dạng của đầu vào của bạn là hằng số và dễ phân tích cú pháp bằng cách tách bạn * nên * sử dụng tách thay vì regex. –

Trả lời

20

Bạn thân thiết. Một cái gì đó như thế này có thể giúp:

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

@Alex Tất nhiên, phụ thuộc vào loại bạn thực sự cần. Bạn có được ý tưởng. –

+0

Chết tiệt. Đã được trong quá trình viết gần như một cái gì đó giống hệt nhau. Thanh danh. –

+0

Tuyệt vời, cảm ơn! Chỉ cần quên phần {} mới. – NullReference

6

Giả sử bạn có một lớp Coordinate với một constructor public Coordinate(double x, double y), bạn có thể làm điều nà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(); 

hoặc tương đương

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

Đó có phải là một điều cần thiết mà bạn sử dụng LINQ? Bạn có thể làm tất cả với chức năng tách chuỗi tiêu chuẩn:

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

Vâng, nhưng nhìn gọn gàng hơn với linq. :) –

+1

@RobertP: Tôi cho rằng đó là chủ quan. Điều này trông khá đơn giản và sạch sẽ với tôi. –

1

Tôi có thể thêm một chút nữa. Nhờ dtb cho sự khởi đầu, upvoted. Nếu bạn phá vỡ chức năng phân tích cú pháp của mình, bạn có thể xử lý các điều kiện lỗi một cách rõ ràng hơn, chẳng hạn như số lượng phần tử sai trong mảng của bạn hoặc những thứ không phân tích thành số thập phân.

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

Bạn có thể làm điều này:

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

Sau đó, bạn có thể tạo ra một bộ sưu tập của các lớp học GeoCoordinate thusly:

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

Bạn đánh tôi với nó! :) – SouthShoreAK

+0

Heh ... StackOverflow có thể là khá cuộc đua, phải không? –

3

Đây là một 'hơi' thoải mái đoạn hiển thị:

  • được biên dịch trước regexen
  • LINQ to chiếu vô danh loại
  • Văn hóa-aware (đúng) số phân tích và in

Bạn muốn trích xuất mã nhất định (ví dụ số phân tích cú pháp) trong cuộc sống thực.

Xem nó 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 } 
Các vấn đề liên quan