在 C# 中有没有一种方法可以在不使用循环的情况下将多维数组的每个值设置为特定值?我找到了 Array.Fill但它似乎只适用于一维数组。
基本上我要找的是这样的东西:
double[,,,] arrayToFill = new double[7,8,9,10];
Array.FillWhole(arrayToFill, 1.2345);
当然可以只使用嵌套循环,但在处理高维数组时不是很烦人吗?
最佳答案
(请参阅此答案中的最后一个代码示例以获得最佳解决方案。)
您实际上可以使用 Span<T>
这样做,但它看起来很繁琐!
double[,,,] arrayToFill = new double[7, 8, 9, 10];
var data = MemoryMarshal.CreateSpan(
ref Unsafe.As<byte, double>(ref MemoryMarshal.GetArrayDataReference(arrayToFill)),
arrayToFill.Length);
data.Fill(1.2345);
foreach (var value in arrayToFill)
{
Console.WriteLine(value); // All values are 1.2345
}
你可以写一个方法来封装这个:
public static void FillArray<T>(Array array, T value)
{
var data = MemoryMarshal.CreateSpan(
ref Unsafe.As<byte, T>(ref MemoryMarshal.GetArrayDataReference(array)),
array.Length);
data.Fill(value);
}
然后调用站点变得更具可读性:
double[,,,] arrayToFill = new double[7, 8, 9, 10];
FillArray(arrayToFill, 1.2345);
foreach (var value in arrayToFill)
{
Console.WriteLine(value); // All values are 1.2345
}
如果你想要更花哨,你可以将它封装在一个扩展方法中:
public static class ArrayExt
{
public static void Fill<T>(this Array array, T value)
{
var data = MemoryMarshal.CreateSpan(
ref Unsafe.As<byte, T>(ref MemoryMarshal.GetArrayDataReference(array)),
array.Length);
data.Fill(value);
}
}
然后你可以这样调用它:
double[,,,] arrayToFill = new double[7, 8, 9, 10];
arrayToFill.Fill(1.2345);
foreach (var value in arrayToFill)
{
Console.WriteLine(value); // All values are 1.2345
}
重要!您必须确保使用正确的类型来填充数组。如果您指定了错误的类型,它将用垃圾填充数组,例如:
arrayToFill.Fill(1);
真的会把事情搞砸。
在此示例中,您需要执行 arrayToFill.Fill<double>(1);
指定正确的类型,否则它会推断出填充数组的错误类型。
根据来自/u/charlieface 的评论,您可以通过为每个数组维度添加强类型重载来规避此问题,因此:
这可能是最好的方法:
public static class ArrayExt
{
public static void Fill<T>(this T[,] array, T value) => fill(array, value);
public static void Fill<T>(this T[,,] array, T value) => fill(array, value);
public static void Fill<T>(this T[,,,] array, T value) => fill(array, value);
public static void Fill<T>(this T[,,,,] array, T value) => fill(array, value);
static void fill<T>(Array array, T value)
{
var data = MemoryMarshal.CreateSpan(
ref Unsafe.As<byte, T>(ref MemoryMarshal.GetArrayDataReference(array)),
array.Length);
data.Fill(value);
}
// ...etc etc. But does anyone really need more than a 5D array? ;)
}
然后arrayToFill.Fill(1);
将正常工作。
关于c# - 在c#中填充多维数组而不用单值循环,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73401522/