Я пытаюсь взять трехмерный массив и передать его в функцию, но она продолжает сообщать об ошибке из-за неправильного количества индексов внутри []. Я передаю ему 2 значения, чтобы вернуть массив для функции, но мне требуется поместить 3 значения для одного элемента, а не массива.
public void function(int[]) {
// does something
}
static void Main(String[] args) {
int[,,] 3Darr = {{{1,2,3}, {4,5,6}, {7,8,9}}, {{10,11,12}, {13,14,15}, {16,17,18}}};
function(arr[1,2]); // gets error for not passing 3 values
}
Кстати, C# позволяет создавать объект, который действует так же, как если бы он был массивом. Вы можете создать объект, который действует как int[,] или int[,,], из любой коллекции, используя индексированные свойства (также называемые индексаторами). Вот пример: stackoverflow.com/questions/69286156/…





int[,,] — трехмерный массив; к нему можно получить доступ только по всем трем координатам, и результатом этого поиска будет int, а не int[]. Не существует механизма получения int[] от int[,,].
Интересно, возможно, вы имеете в виду неровный массив, поэтому один из:
int[][][]int[,][]int[][,]В качестве альтернативы вы можете получить Span<int> как фрагмент смежных данных из int[,,], просто используя начальную точку ref arr[x,y,z] и количество элементов. В широком смысле диапазон можно сравнить с массивом/вектором (по крайней мере, концептуально).
Span будет работать только в последнем измерении, смотрите мой ответ.
Вам следует использовать зубчатый массив (массив массива массива) int[][][] вместо трехмерного int[,,]:
int[][][] arr = new int[][][] {
new int[][] {
new int[] {1, 2, 3},
new int[] {4, 5, 6},
new int[] {7, 8, 9},
},
new int[][] {
new int[] {11, 12, 13},
new int[] {14, 15, 16},
new int[] {17, 18, 19},
},
};
function(arr[1][2]);
Если измерение, по которому вы хотите выполнить итерацию, является последним (т. е. вы указали все остальные), то вы можете использовать Span<T> со следующими функциями расширения
public static Span<T> AsSpan<T>(this Array array) =>
MemoryMarshal.CreateSpan(ref Unsafe.As<byte, T>(ref MemoryMarshal.GetArrayDataReference(array)), array.Length);
public static Span<T> SliceLastDim<T>(this T[,,] array, int dim1, int dim2) =>
array.AsSpan<T>().Slice(((dim1 * array.GetLength(0)) + dim2) * array.GetLength(1), array.GetLength(2));
Затем, чтобы получить нужную строку, просто умножьте остальные измерения.
public void function(Span<int> span)
{
// does something
}
static void Main(String[] args)
{
int[,,] _3Darr = {{{1,2,3}, {4,5,6}, {7,8,9}}, {{10,11,12}, {13,14,15}, {16,17,18}}};
var span = _3Darr.SliceLastDim(1, 2);
function(span);
}
Более общее решение могло бы нарезать произвольное количество измерений. Опять же, указанные вами размеры идут справа налево, а остальные нарезаются. Результат - единственный Span<T>.
public static Span<T> Slice2D<T>(this Array array, params int[] dims)
{
if (dims.Length >= array.Rank - 1)
throw new InvalidOperationException("Too many dimensions");
var offset = 0;
for (var i = 0; i < dims.Length; i++)
offset = (offset + dims[i]) * array.GetLength(i);
var size = 1;
for (var i = dims.Length; i < array.Rank; i++)
size *= array.GetLength(i);
return array.AsSpan<T>().Slice(offset, size);
}
Какой тип
arr? Я вижу объявленный3Darr, но неarr(я не думаю, что3Darrявляется допустимым символом C#, не так ли?). Рассмотрите возможность переформатирования выражения инициализации массива, его очень трудно читать (по крайней мере, на моем телефоне).