多次元配列から単一の次元を取得する方法を理解しようとしています(議論のために、2Dだとしましょう)。多次元配列があります。
double[,] d = new double[,] { { 1, 2, 3, 4, 5 }, { 5, 4, 3, 2, 1 } };
ジャグ配列の場合は、単純に呼び出すd[0]
と、の配列が得られますが{1, 2, 3, 4, 5}
、2D配列で同じことを実現する方法はありますか?
多次元配列から単一の次元を取得する方法を理解しようとしています(議論のために、2Dだとしましょう)。多次元配列があります。
double[,] d = new double[,] { { 1, 2, 3, 4, 5 }, { 5, 4, 3, 2, 1 } };
ジャグ配列の場合は、単純に呼び出すd[0]
と、の配列が得られますが{1, 2, 3, 4, 5}
、2D配列で同じことを実現する方法はありますか?
いいえ。もちろん、スライスを表し、内部にインデクサーを持つラッパークラスを作成することもできますが、何も組み込まれていません。もう1つのアプローチは、スライスのコピーを作成してベクトルを返すメソッドを作成することです。これは、コピーが必要かどうかによって異なります。
using System;
static class ArraySliceExt
{
public static ArraySlice2D<T> Slice<T>(this T[,] arr, int firstDimension)
{
return new ArraySlice2D<T>(arr, firstDimension);
}
}
class ArraySlice2D<T>
{
private readonly T[,] arr;
private readonly int firstDimension;
private readonly int length;
public int Length { get { return length; } }
public ArraySlice2D(T[,] arr, int firstDimension)
{
this.arr = arr;
this.firstDimension = firstDimension;
this.length = arr.GetUpperBound(1) + 1;
}
public T this[int index]
{
get { return arr[firstDimension, index]; }
set { arr[firstDimension, index] = value; }
}
}
public static class Program
{
static void Main()
{
double[,] d = new double[,] { { 1, 2, 3, 4, 5 }, { 5, 4, 3, 2, 1 } };
var slice = d.Slice(0);
for (int i = 0; i < slice.Length; i++)
{
Console.WriteLine(slice[i]);
}
}
}
その答えの改善されたバージョン:
public static IEnumerable<T> SliceRow<T>(this T[,] array, int row)
{
for (var i = array.GetLowerBound(1); i <= array.GetUpperBound(1); i++)
{
yield return array[row, i];
}
}
public static IEnumerable<T> SliceColumn<T>(this T[,] array, int column)
{
for (var i = array.GetLowerBound(0); i <= array.GetUpperBound(0); i++)
{
yield return array[i, column];
}
}
長方形のアレイは、この目的のために構築されていません。このタイプの機能が必要な場合は、ジャグ配列に切り替える必要があります。長方形の配列をギザギザの配列に変換する関数を作成するのは非常に簡単です。
適切なディメンションでGetLength(intディメンション)を呼び出し、適切にインデックスを付けて各値を取得することで、その配列を再構築することもできます。配列全体を変換するよりも安価ですが、最も安価なオプションは、ジャグ配列を使用するように変更することです。
これにより、ジャグ配列のa[r]機能が複製されます。
T[] Slice<T>(T[,] a, int r) => Enumerable.Range(0, a.GetUpperBound(1) + 1).Select(i => a[r, i]).ToArray();