我需要知道如何修改或如何在没有For循环的情况下初始化2d数组的所有元素?
我是指如何使用Extension方法或使用LINQ来做到这一点!?
我试图使用“IEnumerable.Cast<>”来做延期,但没有结果!
而且我不知道为什么?
string[,] m2d = new string[8, 8];
Array.ForEach(m2d.Cast<string>().ToArray(), el => el = "sample1");
即使使用for循环也没有结果...
for (int i = 0; i <= m2d.Cast<string>().ToArray().GetUpperBound(0); i++)
{
m2d.Cast<string>().ToArray()[i] = "sample2";
}
但请忘记这个循环!
试着用一行表达式来做!
像这个不起作用......
m2d.Cast<string>().ToList().ForEach(el => el = "sample3");
谢谢!
答案 0 :(得分:1)
它不起作用,因为通过赋值,您只需将ToList()
或ToArray()
方法创建的集合中的值替换为新值。因为这两种方法实际上都返回了新的集合,所以您的起始数组不会受到您所做的更改的影响。
当然,最明显的方法是使用两个嵌套的for循环。不确定为什么要避免使用它们但是如果你真的想使用ForEach
,你可以枚举数组维度的索引,而不是它的元素,就像功能方法一样。像这样:
Enumerable.Range(0, m2d.GetUpperBound(0) + 1).ToList()
.ForEach(i => Enumerable.Range(0, m2d.GetUpperBound(1) + 1).ToList()
.ForEach(j => m2d[i, j] = "sample"));
答案 1 :(得分:0)
虽然@Dmitry的答案几乎涵盖了why the original attempt has failed以及你应该做些什么来纠正,但是,根据你的要求,你可能还想考虑将数组中的每个项目/索引包装成一些参考类型,能够更改原始数组项:
public class MultiDimensionArrayItemReference<T>
{
private readonly Array _array;
private readonly Int32[] _indices;
public MultiDimensionArrayItemReference(Array array, params Int32[] indices)
{
if (array == null)
throw new ArgumentNullException(paramName: nameof(array));
if (indices == null)
throw new ArgumentNullException(paramName: nameof(indices));
this._array = array;
this._indices = indices;
}
public IReadOnlyCollection<Int32> Indices
{
get
{
return this._indices.ToList().AsReadOnly();
}
}
public T Value
{
get
{
return (T)this._array.GetValue(this._indices);
}
set
{
this._array.SetValue(value, this._indices);
}
}
public override string ToString()
{
return $"[{String.Join(", ", this._indices)}]:{this.Value}";
}
}
public static class MultiDimensionArrayItemReferenceExtensions
{
// That's for the two-dimensional array, but with some effort it can be generalized to support any arrays.
public static IEnumerable<MultiDimensionArrayItemReference<T>> EnumerateReferenceElements<T>(this T[,] array)
{
if (array == null)
throw new ArgumentNullException(paramName: nameof(array));
// Assume zero-based
var rows = array.GetLength(0);
var columns = array.GetLength(1);
for (int row = 0; row < rows; row++)
{
for (int col = 0; col < columns; col++)
{
yield return new MultiDimensionArrayItemReference<T>(
array,
row,
col);
}
}
}
}
...
private static void PrintArray<T>(T[,] array)
{
// Assume zero-based
var rows = array.GetLength(0);
var columns = array.GetLength(1);
for (int row = 0; row < rows; row++)
{
for (int col = 0; col < columns; col++)
{
Console.Write("{0, 7}", array[row, col]);
}
Console.WriteLine();
}
}
...
var array = new [,]
{
{ "a1", "a2" },
{ "b1", "b2" }
};
PrintArray(array);
Console.WriteLine();
var elements = array
.EnumerateReferenceElements()
.ToList();
foreach (var elem in elements)
{
Console.WriteLine(elem);
}
elements.ForEach(
elem =>
elem.Value = elem.Value + "_n");
Console.WriteLine();
PrintArray(array);
将产生以下输出:
a1 a2 b1 b2 [0, 0]:a1 [0, 1]:a2 [1, 0]:b1 [1, 1]:b2 a1_n a2_n b1_n b2_n
由于需要存储每个项目的索引,因此效率不高,但对于一些罕见的情况仍然是可能的解决方案。