C# 有没有更好的方法来使用 LINQ 拆分这个字符串?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10080341/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-09 12:22:46  来源:igfitidea点击:

Is there a better way to split this string using LINQ?

c#linq

提问by NullReference

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?

我有一些经度\纬度坐标聚集在一个字符串中,我想将其拆分为经度\纬度对。多亏了 stackoverflow,我才能够想出一些 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
}

采纳答案by Mehrdad Afshari

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

回答by dtb

Assuming you have a Coordinateclass with a public Coordinate(double x, double y)constructor, you can do this:

假设你有一个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();

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

回答by Adam V

Is it a necessity that you use LINQ? You can do it all with standard string splitting functionality:

您是否有必要使用 LINQ?您可以使用标准字符串拆分功能完成所有操作:

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

回答by SouthShoreAK

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.

我可能会补充一点。感谢 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]);
}

回答by Ethan Brown

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:

然后你可以这样创建一个 GeoCoordinate 类的集合:

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

回答by sehe

Here is a ‘somewhat' nice snippet showing:

这是一个“有点”不错的片段,显示:

  • precompiled regexen
  • LINQ to anonymous type projection
  • Culture-aware (correct) number parsing and printing
  • 预编译的正则表达式
  • LINQ 到匿名类型投影
  • 文化感知(正确)数字解析和打印

You would want to extract certain code (e.g. the number parsing) in real life.

您可能希望在现实生活中提取某些代码(例如数字解析)。

See it live on Ideone.com.

看到它住在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 }

回答by GSoft Consulting

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