C# 展平N阵列

C# 展平N阵列,c#,arrays,C#,Arrays,我有两个相同类型和大小(L)的数组,如果第二个数组的值为0,我想将它们展平为一个数组,或者展平为一个新数组。例如: Arr1 = { 0, 1, 2, 5, 0, 7, 6, 8 } Arr2 = { 0, 0, 3, 1, 9, 2, 0, 1 } Flat = { 0, 1, 3, 1, 9, 2, 6, 1 } 我意识到我可以通过比较来迭代(见下文),但我觉得应该有一种更好的方式来表达和执行这个操作(希望以最大的效率) …我想这在代码中可能是这样的: // Assume collecti

我有两个相同类型和大小(L)的数组,如果第二个数组的值为0,我想将它们展平为一个数组,或者展平为一个新数组。例如:

Arr1 = { 0, 1, 2, 5, 0, 7, 6, 8 }
Arr2 = { 0, 0, 3, 1, 9, 2, 0, 1 }
Flat = { 0, 1, 3, 1, 9, 2, 6, 1 }
我意识到我可以通过比较来迭代(见下文),但我觉得应该有一种更好的方式来表达和执行这个操作(希望以最大的效率)

…我想这在代码中可能是这样的:

// Assume collection is ordered via some predicate
// var myArrays = existingArrays.OrderByDescending(myPredicate).ToList();

// Some function to flatten position 'index'
int FlattenOrderedValues(IEnumerable<int[]> arrays, int index)
{
    for (int i = 0; i < arrays.Lenth)
    {
        if (arrays[i][index] > 0) return (arrays[i][index];
    }

    return 0;
}

for (var i = 0; i < arrays[0].Length; i++)
{
    arrays[0][i] = FlattenOrderedValues(arrays, i);
}
//假设集合是通过某个谓词排序的
//var myArrays=existingArrays.OrderByDescending(myPredicate.ToList();
//一些用于平展位置“索引”的函数
整型FlatOrderedValues(IEnumerable数组,整型索引)
{
对于(int i=0;i0)返回(数组[i][index];
}
返回0;
}
对于(var i=0;i<数组[0]。长度;i++)
{
数组[0][i]=FlatteredValues(数组,i);
}
使用LINQ,您可以同时使用两个数组,并根据两个数组中两个对应项的值选择结果:

var Flat = Arr1.Zip(Arr2, (a1, a2) => a2 == 0 ? a1 : a2).ToArray()

如果有N个数组,则可以多次应用相同的方法。但这将不是非常有效。因此,通过索引访问的简单
for
循环将完成此任务。或者您可以再次使用LINQ通过索引访问所有数组:

var Flat =  Enumerable.Range(0, Arr1.Length)
                      .Select(i => Arr2[i] == 0 ? Arr1[i] : Arr2[i]) // use N arrays here
                      .ToArray()
更新(对于您的示例)。您只需为每个索引选择“列”,然后选择大于零的最后一个值

var Flat = Enumerable.Range(0, arrays[0].Length)
                     .Select(i => arrays.Select(a => a[i]).LastOrDefault(x => x > 0))
                     .ToArray();
使用LINQ,您可以同时使用两个数组并根据两个数组中两个对应项的值选择结果:

var Flat = Arr1.Zip(Arr2, (a1, a2) => a2 == 0 ? a1 : a2).ToArray()

如果有N个数组,则可以多次应用相同的方法。但这将不是非常有效。因此,通过索引访问的简单
for
循环将完成此任务。或者您可以再次使用LINQ通过索引访问所有数组:

var Flat =  Enumerable.Range(0, Arr1.Length)
                      .Select(i => Arr2[i] == 0 ? Arr1[i] : Arr2[i]) // use N arrays here
                      .ToArray()
更新(对于您的示例)。您只需为每个索引选择“列”,然后选择大于零的最后一个值

var Flat = Enumerable.Range(0, arrays[0].Length)
                     .Select(i => arrays.Select(a => a[i]).LastOrDefault(x => x > 0))
                     .ToArray();

在阅读Sergey的答案时,我想到了这个:

int[] Arr1 = { 0, 1, 2, 5, 0, 7, 6, 8 };
int[] Arr2 = { 0, 0, 3, 0, 9, 2, 0, 1 };
int[] Arr3 = { 0, 2, 1, 0, 1, 0, 0, 0 };

int[][] arrays = { Arr1, Arr2, Arr3 };

int[] result = arrays.Aggregate((a, b) => a.Zip(b, (i, j) => j == 0 ? i : j).ToArray());

在阅读Sergey的答案时,我想到了这个:

int[] Arr1 = { 0, 1, 2, 5, 0, 7, 6, 8 };
int[] Arr2 = { 0, 0, 3, 0, 9, 2, 0, 1 };
int[] Arr3 = { 0, 2, 1, 0, 1, 0, 0, 0 };

int[][] arrays = { Arr1, Arr2, Arr3 };

int[] result = arrays.Aggregate((a, b) => a.Zip(b, (i, j) => j == 0 ? i : j).ToArray());

阅读这些答案,我想从我自己身上得到一些东西。即使这些答案很好用……它们太长了,不适合它们必须做的事情

我的解决方案是将所有这些数组打包成一个数组,然后简单地使用
SelectMany
方法将这些数组自动缝合成一个数组

int [] combinedarrays = { array1, array2, array3 };
int [] result = combinedarrays. SelectMany (i => i).Distinct ().ToArray ();

阅读这些答案,我想从我自己身上得到一些东西。即使这些答案很好用……它们太长了,不适合它们必须做的事情

我的解决方案是将所有这些数组打包成一个数组,然后简单地使用
SelectMany
方法将这些数组自动缝合成一个数组

int [] combinedarrays = { array1, array2, array3 };
int [] result = combinedarrays. SelectMany (i => i).Distinct ().ToArray ();

你能为3个数组添加样本吗?将使用什么算法来计算值我为多个数组添加了一个样本,它将所有内容平铺到第一个数组中。请注意,我还没有测试这些样本。假设这些数组表示一个带有z索引的层,它们是按顺序排列的。你当前的算法略有不同-它返回first非零值。即平面将是
{0,1,2,5,9,7,6,8}
。您应该以相反的顺序枚举数组。我可能不应该将结果写入排序示例中的第一个数组,而是写入一个新数组。我希望“OrderByDescending”可以说明这种反转。通过对列表进行反向排序,我将第一个数组视为最后一个数组。您可以为3 ar添加示例吗射线?将使用什么算法来计算值?我已为多个阵列添加了一个样本,将所有内容展平到第一个阵列中。请注意,我尚未测试这些样本。假设这些阵列表示一个具有某个z索引的层,它们按其排序。您当前的算法略有不同-它返回第一个非零值。即Fl至少是
{0,1,2,5,9,7,6,8}
。您应该以相反的顺序枚举数组。我可能不应该将结果写入排序示例中的第一个数组,而是写入一个新数组。我希望“OrderByDescending”可以说明这种反转。通过对列表进行反向排序,我将第一个数组视为最后一个数组。很酷,可能不是最好的性能mance(过早优化是邪恶的),但非常readable@SergeyBerezovskiy是的,我讨厌重复的
ToArray
,但要修复它,代码会变长。很酷,可能不是最好的性能(过早优化是有害的)但是非常readable@SergeyBerezovskiy是的,我讨厌重复的
排列
,但要修复它,代码会变长。