C# 如何在C语言中迭代三维字符串数组#

C# 如何在C语言中迭代三维字符串数组#,c#,C#,我有一个3D阵列 String[][,] cross = {new String[,]{{"1", "b", "b", "b"}, {"b", "c", "c", "c"}},new String[,]{{"2", "b", "b", "e"}, {"b", "c", "c", "d"}}} 如何迭代这个数组 我想这样迭代 foreach(String[,] abc in cross) //abc must be the first/second 2D array foreach(stri

我有一个3D阵列

String[][,] cross = {new String[,]{{"1", "b", "b", "b"}, {"b", "c", "c", "c"}},new String[,]{{"2", "b", "b", "e"}, {"b", "c", "c", "d"}}}
如何迭代这个数组

我想这样迭代

foreach(String[,] abc in cross) //abc must be the first/second 2D array
  foreach(string[] arr in abc) //arr must hold {"1", "b", "b", "b"} (say)
  {
  }

我尝试了这个方法,但不起作用。

您需要3个级别的嵌套for循环,每个维度一个

foreach (string s in cross.SelectMany(x => x.Cast<string>()))
{
    // Code goes here.
}
问题是:您声明的数组中不存在这样的数组。这可能令人困惑,因为用于声明
T[]
数组的语法与用于声明
T[,]
数组的语法之间存在重叠

让我们写出您的初始化,使其更清晰:

string[][,] cross = {
    new string[,] {
        {"1", "b", "b", "b"},
        {"b", "c", "c", "c"}
    },
    new string[,] {
        {"2", "b", "b", "e"},
        {"b", "c", "c", "d"}
    }
};
我们这里有两个
string[,]
维度为4x2的数组。上面的表达式
{“1”、“b”、“b”、“b”}
并不表示单个数组,而是表示多维数组的一维中的值

要实现你似乎想要的行为,这是正确的:你不能用
字符串[][,]
,但你可以用
字符串[][]

string[][][] cross = new[] {
    new[] {
        new[] {"1", "b", "b", "b"},
        new[] {"b", "c", "c", "c"}
    },
    new[] {
        new[] {"2", "b", "b", "e"},
        new[] {"b", "c", "c", "d"}
    }
};
以上述方式声明
交叉
,可以执行以下操作:

foreach (string[][] abc in cross)
{
    foreach (string[] arr in abc)
    {
        Console.WriteLine(string.Join(", ", arr));
    }
}
foreach(string[,] abc in cross)
 for(int i=0; i < abc.GetLength(0); ++i)
   for(int j=0; j < abc.GetLength(1); ++j)
    { string str = abc[i,j];
    }
或者,借用我最初的建议:

foreach (string[] arr in cross.SelectMany(x => x))
{
    Console.WriteLine(string.Join(", ", arr));
}
输出:

1, b, b, b b, c, c, c 2, b, b, e b, c, c, d 1,b,b,b b、 c,c,c 2,b,b,e b、 c,c,d 给定2D数组的锯齿状数组,您将执行如下的经典迭代

foreach (string[,] array in cross)
{
   for (int i = 0; i < array.GetLength(0); i++)
   {
       for (int j = 0; j < array.GetLength(1); j++)
       {
           string item = array[i, j];
           // do something with item
       }
   }
}
foreach(交叉中的字符串[,]数组)
{
for(int i=0;i
一个
字符串[,]
的工作方式与
字符串[][]
的工作方式不同-它是一个正方形数组,而不是数组数组数组。当您在
foreach
语句中使用它时,枚举器将为您提供单个字符串的序列,类似于以下内容:

foreach (string[][] abc in cross)
{
    foreach (string[] arr in abc)
    {
        Console.WriteLine(string.Join(", ", arr));
    }
}
foreach(string[,] abc in cross)
 for(int i=0; i < abc.GetLength(0); ++i)
   for(int j=0; j < abc.GetLength(1); ++j)
    { string str = abc[i,j];
    }

3D阵列在我看来应该是这样的:

string[, ,] arr = new string[,,]{
    {
        {"a1", "b1", "c1"},
        {"a2", "b2", "c2"},
        {"a3", "b3", "c3"},
    },{
        {"a4", "b4", "c4"},
        {"a5", "b5", "c5"},
        {"a6", "b6", "c6"},
    }
};
可以通过以下方式逐一遍历所有项目:

for (int i = 0; i < arr.GetLength(0); i++)
{
    for (int j = 0; j < arr.GetLength(1); j++)
    {
        for (int k = 0; k < arr.GetLength(2); k++)
        {
            string s = arr[i, j, k];
        }
    }
}
for(int i=0;i
听起来您想要的是以is数组结束包含2D数组的第二个元素,按第一个元素分组。因此,根据您的示例,您希望得到如下结果:

{"1", "b", "b", "b"}
Iteration 1a: {"1", "b", "b", "b"} Iteration 1b: {"b", "c", "c", "c"} Iteration 2a: {"2", "b", "b", "e"} Iteration 2b: {"b", "c", "c", "d"} 不过,这样做效率很低,所以你最好假装一下。如果以后只需要对其进行迭代,则可以创建一个可枚举项:

foreach(string[,] square in cross)
    for(int y = 0; y < square.GetUpperBound(0); y++){
        var inner = GetEnumeratedInner(square, y);
        // now do something with inner
    }

...

static IEnumerable<string> GetEnumeratedInner(string[,] square, int y){
    for(int x = 0; x < square.GetUpperBound(1); x++)
        yield return square[y, x];
}
foreach(字符串[,]在十字架上呈正方形)
for(int y=0;y
如果您确实需要通过索引访问它,就像使用数组一样,那么一个索引类就可以做到这一点:

foreach(string[,] square in cross)
    for(int y = 0; y < square.GetUpperBound(0); y++){
        var inner = new IndexedInner(square, y);
        // now do something with inner
    }

...

// this class should really implement ICollection<T> and System.Collections.IList,
// but that would be too much unimportant code to put here
class IndexedInner<T> : IEnumerable<T>{
    T[,] square;
    int  y;

    public IndexedInner(T[,] square, int y){
        this.square = square;
        this.y      = y;
    }

    public int Length{get{return square.GetLength(1);}}

    public T this[int x]{
        get{return square[y, x];}
        set{square[y, x] = value;}
    }

    public IEnumerator<T> GetEnumerator(){
        for(int x = 0; x < square.GetUpperBound(1); x++)
            yield return square[y, x];
    }
    System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator(){
        return GetEnumerator();
    }
}
foreach(字符串[,]在十字架上呈正方形)
for(int y=0;y
您目前有一个由2D数组组成的锯齿状数组。**我建议使用对象或字符串列表而不是3D数组,这样可以更容易地遍历数组,并且可以通过这种方式提取每个元素。对我最初的要求还有什么建议吗?@Vinod:对不起,错过了你最初的要求。我会更新。
foreach(string[,] square in cross)
    for(int y = 0; y < square.GetUpperBound(0); y++){
        var inner = GetEnumeratedInner(square, y);
        // now do something with inner
    }

...

static IEnumerable<string> GetEnumeratedInner(string[,] square, int y){
    for(int x = 0; x < square.GetUpperBound(1); x++)
        yield return square[y, x];
}
foreach(string[,] square in cross)
    for(int y = 0; y < square.GetUpperBound(0); y++){
        var inner = new IndexedInner(square, y);
        // now do something with inner
    }

...

// this class should really implement ICollection<T> and System.Collections.IList,
// but that would be too much unimportant code to put here
class IndexedInner<T> : IEnumerable<T>{
    T[,] square;
    int  y;

    public IndexedInner(T[,] square, int y){
        this.square = square;
        this.y      = y;
    }

    public int Length{get{return square.GetLength(1);}}

    public T this[int x]{
        get{return square[y, x];}
        set{square[y, x] = value;}
    }

    public IEnumerator<T> GetEnumerator(){
        for(int x = 0; x < square.GetUpperBound(1); x++)
            yield return square[y, x];
    }
    System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator(){
        return GetEnumerator();
    }
}