foreach (String s in arrayOfMessages)
{
System.Console.WriteLine(s);
}
string[,] arrayOfMessages
est transmis en tant que paramètre.
Je veux être capable de déterminer quelles chaînes sont à partir de arrayOfMessages[0,i]
et arrayOfMessages[n,i]
, où n
est l'indice final du tableau.
Utilisez simplement deux boucles for
imbriquées. Pour obtenir les tailles des dimensions, vous pouvez utiliser GetLength()
:
for (int i = 0; i < arrayOfMessages.GetLength(0); i++)
{
for (int j = 0; j < arrayOfMessages.GetLength(1); j++)
{
string s = arrayOfMessages[i, j];
Console.WriteLine(s);
}
}
Cela suppose que vous avez réellement string[,]
. Il est également possible d’utiliser des tableaux multidimensionnels non indexés à partir de 0. Dans ce cas, ils doivent être représentés par Array
en C # et vous devez utiliser GetLowerBound()
et GetUpperBound()
pour obtenir les limites de chaque dimension.
Avec une boucle imbriquée:
for (int row = 0; row < arrayOfMessages.GetLength(0); row++)
{
for (int col = 0; col < arrayOfMessages.GetLength(1); col++)
{
string message = arrayOfMessages[row,col];
// use the message
}
}
N'utilisez pas foreach
- utilisez des boucles for
imbriquées, une pour chaque dimension du tableau.
Vous pouvez obtenir le nombre d'éléments dans chaque dimension avec la méthode GetLength
.
Voir Tableaux multidimensionnels (Guide de programmation C #) sur MSDN.
Il semble que vous ayez trouvé une réponse adaptée à votre problème, mais puisque le titre demande un tableau multidimensionnel (que je lis comme 2 ou plus ), et c’est le premier résultat de recherche que j’ai obtenu lors de la recherche, je ajoutera ma solution:
public static class MultidimensionalArrayExtensions
{
/// <summary>
/// Projects each element of a sequence into a new form by incorporating the element's index.
/// </summary>
/// <typeparam name="T">The type of the elements of the array.</typeparam>
/// <param name="array">A sequence of values to invoke the action on.</param>
/// <param name="action">An action to apply to each source element; the second parameter of the function represents the index of the source element.</param>
public static void ForEach<T>(this Array array, Action<T, int[]> action)
{
var dimensionSizes = Enumerable.Range(0, array.Rank).Select(i => array.GetLength(i)).ToArray();
ArrayForEach(dimensionSizes, action, new int[] { }, array);
}
private static void ArrayForEach<T>(int[] dimensionSizes, Action<T, int[]> action, int[] externalCoordinates, Array masterArray)
{
if (dimensionSizes.Length == 1)
for (int i = 0; i < dimensionSizes[0]; i++)
{
var globalCoordinates = externalCoordinates.Concat(new[] { i }).ToArray();
var value = (T)masterArray.GetValue(globalCoordinates);
action(value, globalCoordinates);
}
else
for (int i = 0; i < dimensionSizes[0]; i++)
ArrayForEach(dimensionSizes.Skip(1).ToArray(), action, externalCoordinates.Concat(new[] { i }).ToArray(), masterArray);
}
public static void PopulateArray<T>(this Array array, Func<int[], T> calculateElement)
{
array.ForEach<T>((element, indexArray) => array.SetValue(calculateElement(indexArray), indexArray));
}
}
Exemple d'utilisation:
var foo = new string[,] { { "a", "b" }, { "c", "d" } };
foo.ForEach<string>((value, coords) => Console.WriteLine("(" + String.Join(", ", coords) + $")={value}"));
// outputs:
// (0, 0)=a
// (0, 1)=b
// (1, 0)=c
// (1, 1)=d
// Gives a 10d array where each element equals the sum of its coordinates:
var bar = new int[4, 4, 4, 5, 6, 5, 4, 4, 4, 5];
bar.PopulateArray(coords => coords.Sum());
L'idée générale est de récidiver à travers les dimensions. Je suis sûr que les fonctions ne seront pas récompensées pour l'efficacité, mais cela fonctionne comme un initialiseur unique pour mon réseau et est fourni avec un ForEach assez joli qui expose les valeurs et les indices. Le principal inconvénient que je n'ai pas résolu consiste à le faire reconnaître automatiquement T dans le tableau. Il faut donc faire preuve de prudence en ce qui concerne le type de sécurité.
Quelque chose comme ça marcherait:
int length0 = arrayOfMessages.GetUpperBound(0) + 1;
int length1 = arrayOfMessages.GetUpperBound(1) + 1;
for(int i=0; i<length1; i++) { string msg = arrayOfMessages[0, i]; ... }
for(int i=0; i<length1; i++) { string msg = arrayOfMessages[length0-1, i]; ... }
Une approche plus fonctionnelle consisterait à utiliser LINQ, que je trouve toujours meilleur que les boucles. Cela rend le code plus facile à gérer et à lire. L'extrait de code donné ci-dessous montre l'une des solutions utilisant la syntaxe Method ou Fluent LINQ.
string[,] arrayOfMessages = new string[3, 2] { { "Col1","I am message 1" }, { "Col2", "I am message 2" }, { "Col3", "I am message 3" } };
var result = arrayOfMessages.Cast<string>()
.Where((msg, index) => index % 2 > 0);
foreach (var msg in result)
{
Console.WriteLine(msg);
}
Les méthodes d'extension LINQ ne sont pas disponibles pour les tableaux multidimensionnels car elles n'implémentent pas l'interface IEnumerable<T>
. C'est là que Cast<T>
entre en image. Fondamentalement, tout le tableau est converti en IEnumerable<T>
. Dans notre cas, il va aplatir le tableau multi-dimensionnel en IEnumerable<string>
quelque chose comme:
{ "Col1", "I am message 1", "Col2", "I am message 2", "Col3", "I am message 3" }
Vous pouvez également utiliser OfType<T>
au lieu de Cast<T>
. La seule différence entre eux est que dans le cas de collections avec des types de données mélangés, alors que OfType<T>
ignore les valeurs qu'il est impossible de transtyper, Cast<T>
lève une exception InValidCastException.
Ensuite, il suffit d’appliquer un opérateur LINQ qui ignore (ou filtre) les valeurs aux indices pairs. Nous utilisons donc une surcharge d'opérateur Where
dont le délégué Func est de type Func<TSource, int, bool>
, où TSource
est chaque élément de la collection, int
est l'index de l'élément dans la collection et bool
est le type de retour.
Dans l'extrait ci-dessus, j'ai utilisé une expression lambda qui évalue chaque index d'élément et renvoie vrai uniquement s'il s'agit d'un nombre impair.
Vous pouvez utiliser le code ci-dessous pour exécuter des tableaux multidimensionnels.
foreach (String s in arrayOfMessages)
{
System.Console.WriteLine("{0}",s);
}