簡體   English   中英

將字符串轉換為數組並交換 c# 中元素的兩個值?

[英]Convert string to an Array and swap two value of an elments in c#?

我有一個[Lat, Lng]格式的坐標字符串。

如何將其轉換為 C# 中的[Lng, Lat]格式?

例如:

輸入:

string LatLng = "[[12.06, 106.67],[12.67, 106.68], ... ]" //string

Output:

var LatLng = "[[106.67, 12.06],[106.68, 12.07], ... ]"

首先將字符串分成多個部分,每個部分都包含一個數字(作為字符串):

string LatLng = "[[12.06, 106.67],[12.67, 106.68],[11, 22]]";
string[] parts =
    LatLng.Split(new[] { '[', ']', ',', ' ' }, StringSplitOptions.RemoveEmptyEntries);

然后將數字對創建為 ValueTuples:

var coordinates = Enumerable.Range(0, parts.Length / 2)
    .Select(i => (parts[2 * i], parts[2 * i + 1]));

最后,將這些數字對倒置以形成新坐標:

string mapBoxCoords =
    "[" + String.Join(", ", coordinates.Select(c => $"[{c.Item2}, {c.Item1}]")) + "]";

如果您想做的不僅僅是創建一個新字符串,那么請將坐標轉換為適當的數據結構並且不要使用字符串。 例如,您可以將坐標聲明為

public struct Coordinate
{
    public Coordinate(decimal latitude, decimal longitude)
    {
        Latitude = latitude;
        Longitude = longitude;
    }

    public decimal Latitude { get; }
    public decimal Longitude { get; }

    public string ToLatLngString() => $"[{Latitude}, {Longitude}]";

    public string ToLngLatString() => $"[{Longitude }, {Latitude}]";

    public static IEnumerable<Coordinate> FromLatLngFormat(string latLng)
    {
        string[] parts = latLng.Split(
            new[] { '[', ']', ',', ' ' }, 
            StringSplitOptions.RemoveEmptyEntries);

        return Enumerable.Range(0, parts.Length / 2)
            .Select(i => new Coordinate(Decimal.Parse(parts[2 * i]),
                                        Decimal.Parse(parts[2 * i + 1])));
    }
}

然后進行轉換

var coordinates = Coordinate.FromLatLngFormat(LatLng);
string mapBoxCoords =
    "[" + String.Join(",", coordinates.Select(c => c.ToLngLatString())) + "]";

現在你可以用坐標做很多其他有用的事情。

當您為特定目的操作一組數據時,通常使用 class 來管理它會使 rest 的工作更容易。 如果您要做的不僅僅是重新排列字符串,那么實現這樣的事情通常是 go 的最佳方法(注意:這是一個簡化的示例,顯然除了 null 數據之外,幾乎沒有進行數據完整性/安全性測試,並且范圍檢查,但字符串解析應該相當有彈性:):

class LatLong {
    // Properties
    //
    protected decimal _lat  = 0.0M;
    protected decimal _long = 0.0M;

    // Facilitates validating that strings contain values between -180.0.. and 180.0...
    protected static const string PATTERN = /* language=regex */
        @"^[-+]?(0?[\d]{1,2}([.][\d]*)?|1[0-7][\d]([.][\d]*)?|180([.]0*)?)$";

    // Accessors
    //
    public decimal Latitude 
    { 
        get => _lat;
        set => _lat = Math.Max( Math.Min( 180.0M, value ), -180.0M );
    }

    public decimal Longitude
    { 
        get => _long;
        set => _long = Math.Max( Math.Min( 180.0M, value ), -180.0M );
    }

    // Methods
    //
    public LatLong Swap() => new LatLong() { Longitude = _long, Latitude = _lat };

    public override string ToString() => $"[{Latitude}, {Longitude}]";

    public static LatLong Parse( string data )
    {
        // This function expects data in the form of "###.##, ###.##"
        // with any amount of other non-numeric data sprinkled in. As long as there
        // are two decimal values ranging between -180.0 and +180.0, and
        // separated by a comma, this should be able to parse it.

        if (string.IsNullOrWhiteSpace( data )
            throw new ArgumentException( "Invalid data!" );

        // remove any cruft and split the values
        string[] work = Regex.Replace( data, @"[^-.\d,]", "" ).Split( new char[] { ',' } );

        LatLong result = new LatLong();
        if (work.Length > 0)
            result._lat  = IsValidValue( work[ 0 ] ) ? decimal.Parse( work[ 0 ] ) : 0.00M;

        if (work.Length > 1)
            result._long = IsValidValue( work[ 1 ] ) ? decimal.Parse( work[ 1 ] ) : 0.00M;

        return result;
    }

    public static bool IsValidValue( string test ) =>
        !string.IsNullOrWhiteSpace( test ) && Regex.IsMatch( test.Trim(), PATTERN, RegexOptions.ExplicitCapture );
}

要做你想做的,只需通過 class 解析源數據並使用.Swap() function:

string LatLng = "[[12.06, 106.67],[12.67, 106.68], ... ]", output = "[";
foreach( string s in LatLng.Split( "],[", StringSplitOptions.RemoveEmptyEntries ) )
    output += ((output.Length > 1) ? "," : "") + LatLong.Parse( s ).Swap().ToString();

output += "]";

首先,您需要修剪開方括號和閉合方括號,並用 ],[ 分割字符串以獲取每組坐標。

然后你遍歷每一個並用逗號分隔以分隔緯度和經度。 為了使事情更容易,為這些值創建一個簡單的數據容器。 由於它們 go 回到字符串,您可以將這些值作為字符串,在我的示例中,我解析為浮點數。

在正確解析完所有元素后,您可以再次重建字符串。

private class LatLong
{
    public LatLong(decimal lat, decimal @long)
    {
        Lat = lat;
        Long = @long;
    }

    public decimal Lat { get; set; }
    public decimal Long { get; set; }
}
private void SplitLatLong()
{
    var originalString = "[[24.5, 111.232],[51.2, 112.3],[12, 54.1]]";
    var outputList = new List<LatLong>();

    var itemsSplit = originalString
        .TrimStart(new char[] { '[' })
        .TrimEnd(new char[] { ']' })
        .Split(new string[] { "],[" }, StringSplitOptions.RemoveEmptyEntries);

    foreach (var item in itemsSplit)
    {
        var latLongSplit = item
            .Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);

        outputList.Add(new LatLong(
            decimal.Parse(latLongSplit[1]),
            decimal.Parse(latLongSplit[0]))
        );
    }

    var remerged = "[[" + string.Join("],[", outputList.Select(o => o.Lat + ", " + o.Long)) + "]]";

    // Output the value to make sure it was correct (i am in winforms atm)
    //
    MessageBox.Show(originalString + "\r\n" + remerged);
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM