Преобразование многомерных элементов массива в другой тип

Предположим, у меня есть этот многомерный массив:

float[][,] vertices = { 
            new float[,]{ {0f, 1.28f}, {1.28f, 2.56f}, {3.84f, 2.56f}, {5.12f, 1.28f}, {3.84f, 0f}, {1.28f, 0f}, {0f, 1.28f} }, 
            new float[,]{ {0f, 3.83f}, {1.27f, 5.12f}, {3.87f, 5.12f}, {5.12f, 3.83f}, {5.12f, 1.26f}, {3.87f, 0f}, {1.27f, 0f}, {0f, 1.26f}, {0f, 3.83f} } 
        };

Теперь я хочу преобразовать каждый подмассив в массив типа Vector2[] где Vector2 это публичный класс, который просто содержит x а также y свойства:

public class Vector2 {
  public float x;
  public float y;

  public Vector2(float x, float y) { this.x = x; this.y = y }
}

Поэтому я хочу построить элементы Vector2 из элементов Array[2], которые являются подмассивами выше vertices переменная массива.

Я делаю это так:

Array.ConvertAll(vertices[0], 
    new Converter<float[], Vector2>(verticesSequence => { return new Vector2(verticesSequence[0], verticesSequence[1]); }));

Тем не менее, в ответ я получаю это сообщение об ошибке:

Ошибка 15 Наилучшее совпадение перегруженного метода для 'System.Array.ConvertAll(float[][], System.Converter)' имеет недопустимые аргументы

2 ответа

Решение

У вас есть массив, который содержит два массива, каждый из которых содержит различное количество массивов с плавающей точкой.

Array.ConvertAll подходит для преобразования одного массива в другой путем указания делегата сопоставления (один к одному). В этом случае вам не нужно конвертировать только один float[,] в Vector2, Обратите внимание, что вы также использовали float[] в Vector2 конвертер вместо float[,] в Vector2,

Многомерные массивы, такие как float[,] также немного сложнее, так как они не поддерживают LINQ "из коробки", что немного сложнее создать в одну строку, которая бы выполняла все сопоставления.

Другими словами, вам по крайней мере понадобится вспомогательный метод для сопоставления элементов многомерного массива:

public static IEnumerable<Vector2> ConvertVectors(float[,] list)
{
    for (int row = 0; row < list.GetLength(0); row++)
    {
        yield return new Vector2(list[row, 0], list[row, 1]);
    }
}

И тогда вы можете использовать это внутри Array.ConvertAll метод:

var converted = Array.ConvertAll<float[,], Vector2[]>(
    vertices,
    ff => ConvertVectors(ff).ToArray());

Честно говоря, я бы предпочел решение LINQ, потому что оно автоматически выведет все общие параметры:

var r = vertices
    .Select(v => ConvertVectors(v).ToArray())
    .ToArray();

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

Для ваших нужд может быть проще просто использовать простой цикл

List<Vector2> newList = new List<Vector2>();
foreach (float[,] array in vertices)
    for (int i = 0; i < array.GetLength(0); i++ ) 
        newList.Add(new Vector2(array[i,0], array[i,1]));

Примечание: это перебирает все вершины, поэтому внешний цикл может не потребоваться для ваших нужд.

Другие вопросы по тегам