我需要将n数组(维数未知)转换为1d并将其还原回nd数组。
我遍历整个数组并将元素添加到1d进行转换,但是我不知道如何将其还原。
public class ArrayND<T>
{
private int[] _lengths;
private Array _array;
public ArrayND(int[] length)
{
_lengths = length;
_array = Array.CreateInstance(typeof (T), _lengths);
}
}
///Loop through
public float[] ConvertTo1D(ArrayND<float> ndArray)
{
float[] OneDArray = new float[ndArray.Values.Length];
System.Collections.IEnumerator myEnumerator = ndArray.Values.GetEnumerator();
int cols = ndArray.Values.GetLength(ndArray.Values.Rank - 1);
int j = 0;
while (myEnumerator.MoveNext())
{
OneDArray[j] = (float)myEnumerator.Current;
j++;
}
return OneDArray;
}
答案 0 :(得分:1)
好吧,我以一种奇怪的方式解决了它。我愿意采用更好的方法
public ArrayND<string> convert1DtoND(string[] oneDarray, int[] dimension)
{
ArrayND<string> ndArray = new ArrayND<string>(dimension);
int[] index = new int[ndArray.Values.Rank];
int[] length = new int[ndArray.Values.Rank];
int j = 0;
for (int i = 0; i < length.Length; i++)
{
length[i] = ndArray.Values.GetLength(i);
}
do
{
ndArray[index] = oneDarray[j];
j++;
} while (Increment(index, length));
return ndArray;
}
public static bool Increment(int[] index, int[] length)
{
int i = index.Length - 1;
index[i]++;
while (i >= 0 && index[i] == length[i] && length[i] > 0)
{
index[i--] = 0;
if (i >= 0)
index[i]++;
}
if (i < 0 || length[i] == 0)
return false;
else
return true;
}
答案 1 :(得分:1)
public class ArrayND<T>
{
private int[] _lengths;
private Array _array;
public ArrayND(int[] length)
{
_lengths = length;
_array = Array.CreateInstance(typeof(T), _lengths);
}
public T GetValue(int[] index) => (T)_array.GetValue(index);
public void SetValue(T value, int[] index) => _array.SetValue(value, index);
public T[] ToOneD() => _array.Cast<T>().ToArray();
public static ArrayND<T> FromOneD(T[] array, int[] lengths)
{
if (array.Length != lengths.Aggregate((i, j) => i * j))
throw new ArgumentException("Number of elements in source and destination arrays does not match.");
var factors = lengths.Select((item, index) => lengths.Skip(index).Aggregate((i, j) => i * j)).ToArray();
var factorsHelper = factors.Zip(factors.Skip(1).Append(1), (Current, Next) => new { Current, Next }).ToArray();
var res = new ArrayND<T>(lengths);
for (var i = 0; i < array.Length; i++)
res.SetValue(array[i],
factorsHelper.Select(item => i % item.Current / item.Next).ToArray());
return res;
}
public override bool Equals(object obj) =>
(obj is ArrayND<T> ndArray) &&
_lengths.SequenceEqual(ndArray._lengths) &&
_array.Cast<T>().SequenceEqual(ndArray._array.Cast<T>());
public override int GetHashCode() =>
new[] { 17 }
.Concat(_lengths.Select(i => i.GetHashCode()))
.Concat(_array.Cast<T>().Select(i => i.GetHashCode()))
.Aggregate((i, j) => unchecked(23 * i + j));
}
它可用于任何尺寸。
测试:
int I = 2, J = 3, K = 4;
var a = new ArrayND<int>(new[] { I, J, K });
var v = 0;
for (var i = 0; i < I; i++)
for (var j = 0; j < J; j++)
for (var k = 0; k < K; k++)
a.SetValue(++v, new[] { i, j, k });
var b = a.ToOneD();
var c = ArrayND<int>.FromOneD(b, new[] { I, J, K });
Console.WriteLine(a.Equals(c)); // True
或:
int I = 2, J = 3;
var a = new ArrayND<int>(new[] { I, J });
var v = 0;
for (var i = 0; i < I; i++)
for (var j = 0; j < J; j++)
a.SetValue(++v, new[] { i, j });
var b = a.ToOneD();
var c = ArrayND<int>.FromOneD(b, new[] { I, J });
Console.WriteLine(a.Equals(c)); // True
或:
int I = 2, J = 3, K = 4, M = 5;
var a = new ArrayND<int>(new[] { I, J, K, M });
var v = 0;
for (var i = 0; i < I; i++)
for (var j = 0; j < J; j++)
for (var k = 0; k < K; k++)
for (var m = 0; m < M; m++)
a.SetValue(++v, new[] { i, j, k, m });
var b = a.ToOneD();
var c = ArrayND<int>.FromOneD(b, new[] { I, J, K, M });
Console.WriteLine(a.Equals(c)); // True