C# - 更改多维数组元素类型

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

我有一个在编译时具有未知维度的多维数组但在运行时(当我收到这样的数组时)其维度被描述为int[] dimensionsdimensions的长度等于数组的秩,dimensions的每个元素包含相关维度的长度。

我想要获得的是一个类似的Array,其元素映射到具有不同类型的新对象中。我认为LINQ可能有用所以我写了以下内容:

Array arr = ... //My multi-dimensional Array
var dimensions = ... //array describing the dimensions of arr. (NOT USED in the following but is an information i have)

var transformedArr = arr.Cast<StatusCode>().Select(val => JObject.FromObject(val)).ToArray();

它有效,但transformedArr现在只是一维数组,因此我丢失了我的多维矩阵。您是否有任何想法只能获得具有不同元素类型的相同数组?

请注意,我不知道数组的维度,仅在运行时。换句话说,我不能使用循环来索引多维数组。

任何想法将不胜感激:)

c# arrays multidimensional-array
2个回答
1
投票

我认为以下功能应符合您的要求

public static void RecursiveCopy<TInput, TOutput>(
    Array source,
    Array destination,
    int[] dimensions,
    Func<TInput, TOutput> mutate,
    int[] indexPrefix = null)
{
    indexPrefix = indexPrefix ?? new int[0];
    if (dimensions.Length != 1)
    {
        for (var i = 0; i < dimensions[0]; i++)
        {
            var newDimensions = new int[dimensions.Length - 1];
            Array.Copy(dimensions, 1, newDimensions, 0, dimensions.Length - 1);

            var newIndexPrefix = new int[indexPrefix.Length + 1];
            Array.Copy(indexPrefix, 0, newIndexPrefix, 0, indexPrefix.Length);
            newIndexPrefix[indexPrefix.Length] = i;

            RecursiveCopy(source, destination, newDimensions, mutate, newIndexPrefix);
        }
    }
    else
    {
        var currentIndex = new int[indexPrefix.Length + 1];
        Array.Copy(indexPrefix, 0, currentIndex, 0, indexPrefix.Length);
        for (var i = 0; i < dimensions[0]; i++)
        {
            currentIndex[indexPrefix.Length] = i;
            var value = source.GetValue(currentIndex);
            if (value is TInput)
            {
                var mutated = mutate((TInput)value);
                destination.SetValue(mutated, currentIndex);
            }
            else
            {
                throw new ArgumentException("Different type. Expected " + nameof(TInput));
            }
        }
    }
}

用法

var transformedArr = Array.CreateInstance(typeof(StatusCode), dimensions);
RecursiveCopy<object, StatusCode>(arr, transformedArr, dimensions, i => i as StatusCode);

你可以把真实的类型而不是对象


0
投票

您可以使用CreateInstance创建输出数组(使用dimensions作为输入),然后使用GetValueSetValue来转换您的值。

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