C# 如何从多维数组创建字符串向量?
最初的问题是,我正在从正在开发的工具中读取大量二进制数据 我的目标是读取数据并将其解析为人类可读的文本,如.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:数据0,数据1,数据2,数据3 对于3*4*2:数据0、数据0、数据1、数据0、数据2、数据3、数据1、 等等 我每次都能从该工具获得的唯一信息是数组的尺寸和大小。 该工具可能会告诉我{1},这意味着一个值,{12}意味着一个长度为12,{3,4,5}的数组 表示“3x4x5”元素数组等。。。因此,我需要能够展平任何阵列 a*b*c*.*x的。(这应该不会太难,因为我可以有一个for循环 因此,我想创建一个方法,从任何多维数组生成字符串向量(如上格式) 因此,我认为在最后,头生成方法将类似于C# 如何从多维数组创建字符串向量?,c#,arrays,algorithm,multidimensional-array,C#,Arrays,Algorithm,Multidimensional Array,最初的问题是,我正在从正在开发的工具中读取大量二进制数据 我的目标是读取数据并将其解析为人类可读的文本,如.csv文件,因此我必须将其扁平化 这些数据 数据以多维浮点数、长整数或整数数组的样本形式存在。及 由于该工具正在开发中,阵列的大小和尺寸可能每小时不同 (例如,现在我可能有一个2*2矩阵的样本,两小时后他们可能会将数据结构更改为 1*4或16*12*128的数组,…) 问题的一部分是生成.CSV文件的标题行。我需要一种可以 生成如下所示的字符串数组: 对于2*2:data_0_0、data
public string[] GenerateNames(string dataBlockName, int[] dimensions)
{
}
一个简单的解决方案是使用10个For循环,希望原始数据永远不会有超过10维的数组。但是,我正在寻找更好、更干净、更好的解决方案!
有很多问题都在问如何将一个向量转换成多维数组。我的目标是完全相反的事情,一个具有无限灵活性的标题行
伙计们,先谢谢你们
--
下面有人建议使用“深度优先遍历”,我现在将对此进行研究。最初的谷歌搜索似乎很有希望。您可以通过在
foreach
循环中迭代任何数组,将每个项添加到列表中,然后将该列表转换回数组来展平它
public T[] Flatten<T>(Array array)
{
var list = new List<T>();
foreach (T item in array)
{
list.Add(item);
}
return list.ToArray();
}
public T[]展平(数组)
{
var list=新列表();
foreach(数组中的T项)
{
列表。添加(项目);
}
return list.ToArray();
}
其中,
array
是任何形状的矩形数组。您不需要具有大小的数组,因为您可以使用array类的Rank属性以及获取值的相应方法来检查维度。考虑到这一点以及良好的旧.net 1.0数组类,您可以编写如下方法:
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;
}
public T[]展平(数组源)
{
var arrayIndex=newint[source.Rank];
var result=newt[Enumerable.Range(0,source.Rank).Sum(i=>source.GetUpperBound(i));
var指数=0;
for(var i=0;i
它比foreach更复杂,但它将为您如何遍历原始数组(取决于.net实现)提供更大的灵活性。由于数组不是泛型类,您需要在方法上提供元素类型,因此对于整数数组,您可以将其称为:
Flatten<int>(myArray);
展平(myArray);
缓冲区。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;
}
public T[]展平(数组源)
{
int字节数=缓冲区字节长度(源);
int-sizeofT=缓冲区长度(新的T[1]);
T[]dest=新的T[(字节计数+sizeofT-1)/sizeofT];
块复制(源,0,目标,0,字节数);
返回目的地;
}
数组是矩形的还是锯齿状的?即它是foo[][
还是foo[,]
?事实上,我知道它们是矩形的。对数组进行深度优先遍历。我自己写了一段代码来解决这个问题。我可以稍后将其作为答案发布。有什么特殊情况吗?@RobertHarvey一些未处理的特殊情况是:source
为null或空。source
不是数组>T
可能导致各种大小不匹配或需要解释的映射。