如何交换数组中两个不同长度的变量组 VS C#

问题描述 投票:0回答:2

如何在同一个数组中交换同一个数组的两个不同长度的变量组。即使我需要 C# 中的代码,同时理论过程对我来说就足够了。

我已经尝试了几种方法,但我一直在寻找一种不那么多余和/或不那么重的方法。

例如我有

string[] lines
这些行:

line 0
line 1
line 2
line 3
line 4
line 5
line 6
line 7
line 8

如果你想用第 5 6 行交换第 1 2 3 行,这应该是这样的

line 0
line 5
line 6
line 4
line 1
line 2
line 3
line 7
line 8

n.b. : 每次要交换的行和行数是不同的

我在这里放我的代码https://codereview.stackexchange.com/questions/284597/swap-two-different-length-group-of-variable-in-array-vs-c

c# arrays visual-studio-2022 swap
2个回答
0
投票
public static class Extension
{
    public static string[] Shift(this string[] array, int startIndex, int length, int newIndex)
    {
        string[] items = array.Skip(startIndex).Take(length).ToArray();
        ArrayList arrayList = new ArrayList(array);
        arrayList.RemoveRange(startIndex, length);
        arrayList.InsertRange(newIndex, items);

        arrayList.CopyTo(array);
        return array;
    }
}

private static void Main(string[] args)
{
    string[] array =
        {
        "line 0",
        "line 1",
        "line 2",
        "line 3",
        "line 4",
        "line 5",
        "line 6",
        "line 7",
        "line 8"
    };
    array = array.Shift(5, 2, 1);
    array = array.Shift(3, 3, 4);
}

可以用扩展类来做。没有经过全面测试。


0
投票

有结果

0,1,2,3,4,5,6,7,8,9,10
0,8,9,5,6,7,1,2,3,4,10

我有以下代码:

internal class Program
{
    static void Main(string[] args)
    {
        int[] array = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };

        Console.WriteLine(string.Join(",", array));

        SwapElements(ref array, 1..5, 8..10);

        Console.WriteLine(string.Join(",", array));
    }

    static void SwapElements<T>(ref T[] array, Range a, Range b)
    {
        (int a_Offset, int a_Length) = a.GetOffsetAndLength(array.Length);
        (int b_Offset, int b_Length) = b.GetOffsetAndLength(array.Length);

        if (a_Offset > b_Offset)
        {
            ((b_Offset, b_Length), (a_Offset, a_Length)) = ((a_Offset, a_Length), (b_Offset, b_Length));
        }

        Range pre_a = Range.EndAt(a_Offset);
        a = new Range(a_Offset, a_Offset + a_Length);
        Range between = new Range(a_Offset + a_Length, b_Offset);
        b = new Range(b_Offset, b_Offset + b_Length);
        Range post_b = Range.StartAt(b_Offset + b_Length);

        array = Concat(array[pre_a], array[b], array[between], array[a], array[post_b]);
    }

    /// <summary>
    /// Concatenates two or more arrays into a single one.
    /// </summary>
    /// <remarks>
    /// Code taken from https://stackoverflow.com/a/52749536/380384
    /// </remarks>
    public static T[] Concat<T>(params T[][] arrays)
    {
        // return (from array in arrays from arr in array select arr).ToArray();

        var result = new T[arrays.Sum(a => a.Length)];
        int offset = 0;
        for (int x = 0; x < arrays.Length; x++)
        {
            arrays[x].CopyTo(result, offset);
            offset += arrays[x].Length;
        }
        return result;
    }
}

笔记。

  1. 我正在使用

    Range
    对象来定义要交换的数组切片。我使用从 [SO] 窃取的自定义
    Concat
    函数从不同的切片重新组装数组。在操作之前对切片进行排序,以确保正确定义两个切片之间的元素。

  2. C# 范围出于某种原因使用一些晦涩的概念将

    start
    end
    的范围定义为
    start..(end+1)
    。 70 年前,Fortran 对
    start:end
    做了同样的事情,这是有道理的,此后的所有其他矢量语言(如 Matlab 等),但是当 C# 引入切片时,他们完全 foobar'd 以使其无缘无故地像 Python .吐槽完毕

© www.soinside.com 2019 - 2024. All rights reserved.