最初的问题是我正在从正在开发的工具中读取大块二进制数据。
我的目标是读取数据并将其解析为人类可读的文本,例如.csv文件,所以我必须弄平 那个数据。
数据是浮点数,长数或整数或其他数据的多维数组的样本形式。和 因为该工具正在开发中,所以阵列的大小和尺寸可能因时而异!
(例如,我现在可能有2 * 2矩阵的样本,从现在起两小时后他们可能会将数据结构更改为 1 * 4,或16 * 12 * 128的数组,......)
问题的一部分是生成.CSV文件的标题行。我需要一种可以的方法 生成一个像这样的字符串数组:
表示2 * 2:data_0_0,data_0_1,data_1_0,data_1_1和
表示1 * 4:data_0,data_1,data_2,data_3,
表示3 * 4 * 2:data_0_0_0,data_0_0_1,data_0_0_2,....,data_2_3_0,data_2_3_1,
依旧......
每次我从工具中获得的唯一信息是数组的尺寸和大小。 该工具可能告诉我{1},这意味着单个值,{12}表示长度为12的数组,{3,4,5} 意思是" 3x4x5"元素数组等等......因此,我需要能够展平任何数组 a * b * c * .. * x。 (这不应该太难,因为我可以有一个for循环。
所以,我想创建一个从ANY多维数组生成字符串向量(以上格式)的方法。
因此我认为最后,标题生成方法看起来与此类似
public string[] GenerateNames(string dataBlockName, int[] dimensions)
{
}
一个简单的解决方案是让我们说10个For循环,并希望原始数据永远不会有一个超过10维的数组。但是,我正在寻找更好,更清洁,更好的解决方案! 有很多问题要求如何将矢量更改为多维数组。我的目标是完全相反的事情和具有无限灵活性的标题行!
非常感谢fellas!
- 下面有人建议使用" Depth First Traversal"我现在要调查一下。最初的谷歌搜索似乎很有希望。
答案 0 :(得分:1)
你可以通过在foreach
循环中迭代它,将每个项目添加到列表,然后将该列表转换回数组来展平任何数组。
public T[] Flatten<T>(Array array)
{
var list = new List<T>();
foreach (T item in array)
{
list.Add(item);
}
return list.ToArray();
}
其中array
是任何形状的矩形数组。
答案 1 :(得分:0)
您不需要具有大小的数组,因为您可以使用Array类的Rank属性以及获取值的相应方法来检查维度。考虑到这一点以及良好的旧.net 1.0 Array类,您可以编写类似这样的方法:
public T[] Flatten<T>(Array source)
{
var arrayIndex = new int[source.Rank];
var result = new T[Enumerable.Range(0, source.Rank).Sum(i => source.GetUpperBound(i))];
var index = 0;
for(var i = 0; i < source.Rank; i++)
{
for(var j = 0; j < source.GetUpperBound(i); j++)
{
arrayIndex[i] = j;
result[index++] = (T)source.GetValue(arrayIndex);
}
}
return result;
}
它比foreach更复杂,但它将为您如何遍历原始数组提供更大的灵活性(这取决于.net实现)。由于Array不是泛型类,因此您需要在方法上提供元素类型,以便对于整数数组,您可以将其称为:
Flatten<int>(myArray);
答案 2 :(得分:0)
Buffer.BlockCopy
在这里很方便。
注意:有一些特殊情况要处理,所以把它作为伪代码。
public T[] Flatten<T>(Array source)
{
int byteCount = Buffer.ByteLength(source);
int sizeofT = Buffer.ByteLength(new T[1]);
T[] dest = new T[(byteCount + sizeofT - 1) / sizeofT];
Buffer.BlockCopy(source,0,dest,0,byteCount);
return dest;
}