Как я могу быстро преобразовать объект [,] в double [,]? - PullRequest
13 голосов
/ 22 февраля 2011

Я использую Microsoft.Office.Interop.Excel Мне возвращается двумерный массив типа object[,], который содержит double для элементов.Обратите внимание, что нижняя граница индекса равна 1 вместо значения по умолчанию 0, но я легко справлюсь с этим.

Как приятно преобразовать массив в double[,], используя.NET 3.5.(под красивым словом я имею в виду сжатый или компактный).

Обратите внимание, что

double[] values_2 = values.Cast<double>().ToArray();

работает, но с помощью массива сглаживается в одномерную структуру.

Ответы [ 5 ]

29 голосов
/ 22 февраля 2011
object[,] src = new object[2, 3];

// Initialize src with test doubles.
src[0, 0] = 1.0;
src[0, 1] = 2.0;
src[0, 2] = 3.0;
src[1, 0] = 4.0;
src[1, 1] = 5.0;
src[1, 2] = 6.0;

double[,] dst = new double[src.GetLength(0), src.GetLength(1)];
Array.Copy(src, dst, src.Length);
3 голосов
/ 22 февраля 2011

Я бы не сказал, что есть один способ, который быстрее, чем другой, если вы не делаете глупостей. Я бы сказал, что, если вы можете, разыграйте их, когда получите доступ к ним, а не сразу. Конечно, это зависит от того, как вы намереваетесь получить к ним доступ. Если вы собираетесь индексировать массив более одного раза, тогда стоимость распаковки может стать слишком высокой. Если вы сканируете массив только один раз, то применяйте его на ходу.

2 голосов
/ 18 марта 2016

Это должно работать в большинстве случаев, но может вызвать исключение, если вы не назначаете делегата преобразования.

public static TResult[,] Convert<TSource, TResult>(
    this TSource[,] array, Func<TSource, TResult> conversion = null) {

        if(array == null) throw new ArgumentNullException("array");

        if (conversion == null) {
            var resultType = typeof(TResult);
            conversion = source => (TResult)System.Convert.ChangeType(source, resultType);
        }

        var width = array.GetLength(1);
        var height = array.GetLength(0);
        var result = new TResult[height, width]; 

        for (int i = 0; i < height; ++i)
            for (int j = 0; j < width; ++j)
                result[i, j] = conversion(array[i, j]);

        return result;
    }
1 голос
/ 08 мая 2013
Array.Copy(src, dst, src.Length);

Этот код выдаст ошибку, если любое из значений в src равно нулю. Так как в приведенном выше коде src есть определенное значение, он работает нормально. Если значение src установлено динамически и, к сожалению, если какое-либо из значений равно нулю, приведенный выше код не будет работать. Значение не будет успешно скопировано.

1 голос
/ 22 февраля 2011

Здесь есть пара проблем.

Во-первых, поскольку double не является ссылочным типом, его необходимо поместить в коробку, чтобы сохранить в объекте [], поэтому единственный способ получить значения - это распаковать значения в double [] (copy copy) .

Другая проблема состоит в том, что в C # массивы ковариантны, но не контравариантны, вы можете назначить массив для ссылки более производного типа, а не из менее производного типа.

string[] strings = new string[10];
object[] objects = strings; // OK, covariant
string[] strings2 = objects; // not OK, contravariant
objects[0] = 10; // Compiles fine, runtime ArrayTypeMismatchException!
...