2010-07-15 21 views
7

bien sencilla pregunta aquí (tal vez no una respuesta simple?)¿Encontrar la posición de un elemento en una matriz bidimensional?

Decir que tengo una matriz bidimensional

[0] [1] [2] 
[3] [4] [5] 
[6] [7] [8] 

Ahora supongamos que quiero obtener la posición del número 6

sé con una matriz unidimensional, puedo usar Array.indexOf(), pero ¿cuáles serían mis opciones con las matrices bidimensionales?

Gracias!

+0

supongo que quiere decir una matriz 2D ('int [,]'), no una matriz escalonada ('int [] []') – SLaks

Respuesta

19

yo diría que algo como esto:

public static Tuple<int, int> CoordinatesOf<T>(this T[,] matrix, T value) 
{ 
    int w = matrix.GetLength(0); // width 
    int h = matrix.GetLength(1); // height 

    for (int x = 0; x < w; ++x) 
    { 
     for (int y = 0; y < h; ++y) 
     { 
      if (matrix[x, y].Equals(value)) 
       return Tuple.Create(x, y); 
     } 
    } 

    return Tuple.Create(-1, -1); 
} 
+0

En situaciones como esta, prefiero crear una clase para representar el resultado en lugar de usar una Tupla ya que Tuple no transmite lo que se devuelve. Claro, cuando estás mirando la línea Tuple coordinate = matrix.CoordinatesOf (5) puedes adivinar fácilmente que se trata de una coordenada/punto, pero una vez que ese valor se mueve a través del sistema se convierte en una Tuple dejando un pobre dev para rastrear el fuente para aprender lo que Tuple realmente representa. –

1

Aquí es un método que se debe encontrar un índice en una matriz con un rango arbitrario.

... Agregado superior de la escala/Límites inferior por rango

public static class Tools 
{ 
    public static int[] FindIndex(this Array haystack, object needle) 
    { 
     if (haystack.Rank == 1) 
      return new[] { Array.IndexOf(haystack, needle) }; 

     var found = haystack.OfType<object>() 
          .Select((v, i) => new { v, i }) 
          .FirstOrDefault(s => s.v.Equals(needle)); 
     if (found == null) 
      throw new Exception("needle not found in set"); 

     var indexes = new int[haystack.Rank]; 
     var last = found.i; 
     var lastLength = Enumerable.Range(0, haystack.Rank) 
            .Aggregate(1, 
             (a, v) => a * haystack.GetLength(v)); 
     for (var rank =0; rank < haystack.Rank; rank++) 
     { 
      lastLength = lastLength/haystack.GetLength(rank); 
      var value = last/lastLength; 
      last -= value * lastLength; 

      var index = value + haystack.GetLowerBound(rank); 
      if (index > haystack.GetUpperBound(rank)) 
       throw new IndexOutOfRangeException(); 
      indexes[rank] = index; 
     } 

     return indexes; 
    } 
} 
+0

Esto es muy limpio, pero la llamada 'ToList' me parece un poco vago ... ¿por qué copiar todo el contenido de una matriz multidimensional a' List 'solo para usar' IndexOf'? Puedes escribir el tuyo propio que enumera sobre la matriz en contexto. –

+0

buen punto. Estaba pensando en agregar soporte a los límites del rango de todos modos porque voy a cambiar eso. –

Cuestiones relacionadas