Compruebe si existe una clave específica en la matriz de 2 dimensiones -- php campo con collision camp codereview Relacionados El problema

Check if specific key exists in 2-dimensional array


4
vote

problema

Español

Estoy escribiendo una "detección de colisiones" en PHP y desea verificar si un "área" específico sigue siendo gratuita en la matriz objetivo bidimensional.

Utilizo el siguiente código para hacerlo, pero creo que podría haber una solución mejor (= más rápido) que el bucle superior a todas las posiciones posibles en la matriz y verifique si está configurado o no.

  public function CheckForCollision($top, $left, $size, $collision_array) {         $possible_x = range($left, $left+$size-1);        $possible_y = range($top, $top+$size-1);         // Slow solution, improve this: Check every possible value in the $collision_array with our "might be"-values        foreach($possible_x as $x)        {           foreach($possible_y as $y)           {              if($collision_array[$x][$y] == 1) { return false; break; }           }        }         return true;     }   

¿Alguna idea de esto?

Original en ingles

I am writing a "collision detection" in PHP and want to check if a specific "area" is still free in the two-dimensional target array.

I use the following code to do that, but I think there might be a better (= faster) solution than looping over every possible position in the array and check whether it's set or not.

public function CheckForCollision($top, $left, $size, $collision_array) {         $possible_x = range($left, $left+$size-1);        $possible_y = range($top, $top+$size-1);         // Slow solution, improve this: Check every possible value in the $collision_array with our "might be"-values        foreach($possible_x as $x)        {           foreach($possible_y as $y)           {              if($collision_array[$x][$y] == 1) { return false; break; }           }        }         return true;     } 

Any ideas on this?

     
       
       

Lista de respuestas

3
 
vote
vote
La mejor respuesta
 

Si he entendido su pregunta correctamente, está buscando una función que puede verificar si los valores de una matriz de dos dimensiones es igual FALSE . Un ejemplo de tal estructura de matriz podría ser:

  $array = [     0 => [0, 0, 0, 0, 0],     1 => [0, 0, 0, 0, 0],     2 => [0, 0, 0, 0, 0],     3 => [0, 0, 0, 0, 0],     4 => [0, 0, 0, 0, 0], ];   

He intentado escribir una implementación del contexto que ha dado. He reducido su código a un solo 9988777665544332 bucle y abrió la posibilidad de tener cualquier valor predeterminado que evalúa a FALSE , como false , null , 0 o una matriz vacía. Esto se hace a través del nativo array_filter() Función . También he incluido alguna revisión de errores. Un ejemplo de ejemplo podría ser.

  /*  * Using array structure from previous example.  *  * Check if array elements starting at index 1 and 2  * elements forward only contains values that equals  * to FALSE.  */ $valid = collisions($array, 1, 2);   

junto con los comentarios en línea El código de la función debe ser bastante explicativo.

  /**  * Check if the provided array has any values that does not  * evaluate to FALSE in the given array range.  *  * @param array $array A two dimensional array.  * @param int   $start An integer specifying an array index to start the check.  * @param int   $size  An integer specifying how many array elements to check values for.  *  * @return bool Returns FALSE if there are collisions, TRUE otherwise.  * @throws OutOfRangeException  * @throws DomainException  */ function collisions(array $array, $start, $size) {     /*      * We ensure the outer array has only       * numeric array keys.      */     $array = array_values($array);      /*      * Check if starting index is out of range of the provided array.      */     if(!array_key_exists($start, $array)) {         throw new OutOfRangeException('The specified starting index is out of range of the provided array.');     }      /*      * Compute the upper boundary      */     $boundary = (int)$start + (int)$size;      /*      * Check if the amount of elements to check AFTER the specified starting      * index is out of range of the provided array.      */     if(!array_key_exists($boundary, $array)) {         throw new OutOfRangeException('The specified amount of elements to check exhausts the provided array.');     }      for($i = (int)$start; $i <= $boundary; $i++) {          /*          * Check if the current array value is an array.          */         if(!is_array($array[$i])) {             throw new DomainException("Invalid type of array value at index {$i}. Expected an array, type of " . gettype($array[$i]) . ' given.');         }          /*          * If the native function array_filter() doesn't have a second          * argument, it will filter out any values corresponding to FALSE. I assume          * an accepted value is 0, which evaluates to FALSE.          *          * Therefore of the resulting array is NOT empty there are          * values which does not equal to 0 (zero).          */         if(array_filter($array[$i])) {             return false;         }      }      return true; }   

La comprobación de errores y la primera línea 99887776655443310 Se puede eliminar si está seguro de que la matriz proporcionada siempre tiene la estructura correcta y tiene índices numéricos. Pero recomendaría encarecidamente que no lo haga, ya que una buena revisión de errores puede ayudarlo cuando ocurren errores.

Responsable Sabio Esto no debería ser demasiado malo. Los muchos $array = [ 0 => [0, 0, 0, 0, 0], 1 => [0, 0, 0, 0, 0], 2 => [0, 0, 0, 0, 0], 3 => [0, 0, 0, 0, 0], 4 => [0, 0, 0, 0, 0], ]; 11 Las declaraciones al verificar los errores son algo lentas, pero deben ser insignificantes. Por lo que sé, el bucle 99887776655443312 no funciona en una copia de la matriz proporcionada como $array = [ 0 => [0, 0, 0, 0, 0], 1 => [0, 0, 0, 0, 0], 2 => [0, 0, 0, 0, 0], 3 => [0, 0, 0, 0, 0], 4 => [0, 0, 0, 0, 0], ]; 3 de lo contrario. Esto es solo una preocupación si está teniendo grandes matrices. Si este es el caso, recomendaría encarecidamente usar un $array = [ 0 => [0, 0, 0, 0, 0], 1 => [0, 0, 0, 0, 0], 2 => [0, 0, 0, 0, 0], 3 => [0, 0, 0, 0, 0], 4 => [0, 0, 0, 0, 0], ]; 4 .

con respecto al rendimiento. La optimización prematura casi siempre no es la respuesta. Le sugeriría que escriba código sólido . Luego, cuando haya terminado, puede perfilar su solicitud y buscar bloques pesados ​​de rendimiento. Recuerde que si su solicitud se basa en una base de datos, las mayores ganancias de rendimiento están correctamente en la escritura de consultas SQL altamente optimizadas. Por supuesto hay excepciones. Si esta función se usa ampliamente a lo largo de su código, siempre es bueno pensar en la optimización.

¡Feliz codificación!

 

If I have understood your question correctly you are seeking a function which can check if values of a 2-dimensional array equals FALSE. An example of such array structure could be:

$array = [     0 => [0, 0, 0, 0, 0],     1 => [0, 0, 0, 0, 0],     2 => [0, 0, 0, 0, 0],     3 => [0, 0, 0, 0, 0],     4 => [0, 0, 0, 0, 0], ]; 

I have attempted to write an implementation from the context you have given. I have reduced your code down to a single for loop and opened the possibility to having any default value that evaluates to FALSE, such as false, null, 0 or an empty array. This is done through the native array_filter() function. I have also included some error checking. An example usage could be.

/*  * Using array structure from previous example.  *  * Check if array elements starting at index 1 and 2  * elements forward only contains values that equals  * to FALSE.  */ $valid = collisions($array, 1, 2); 

Along with inline comments the code of the function should be pretty self explanatory.

/**  * Check if the provided array has any values that does not  * evaluate to FALSE in the given array range.  *  * @param array $array A two dimensional array.  * @param int   $start An integer specifying an array index to start the check.  * @param int   $size  An integer specifying how many array elements to check values for.  *  * @return bool Returns FALSE if there are collisions, TRUE otherwise.  * @throws \OutOfRangeException  * @throws \DomainException  */ function collisions(array $array, $start, $size) {     /*      * We ensure the outer array has only       * numeric array keys.      */     $array = array_values($array);      /*      * Check if starting index is out of range of the provided array.      */     if(!array_key_exists($start, $array)) {         throw new OutOfRangeException('The specified starting index is out of range of the provided array.');     }      /*      * Compute the upper boundary      */     $boundary = (int)$start + (int)$size;      /*      * Check if the amount of elements to check AFTER the specified starting      * index is out of range of the provided array.      */     if(!array_key_exists($boundary, $array)) {         throw new OutOfRangeException('The specified amount of elements to check exhausts the provided array.');     }      for($i = (int)$start; $i <= $boundary; $i++) {          /*          * Check if the current array value is an array.          */         if(!is_array($array[$i])) {             throw new DomainException("Invalid type of array value at index {$i}. Expected an array, type of " . gettype($array[$i]) . ' given.');         }          /*          * If the native function array_filter() doesn't have a second          * argument, it will filter out any values corresponding to FALSE. I assume          * an accepted value is 0, which evaluates to FALSE.          *          * Therefore of the resulting array is NOT empty there are          * values which does not equal to 0 (zero).          */         if(array_filter($array[$i])) {             return false;         }      }      return true; } 

The error checking and the first line $array = array_values($array); can be removed if you are sure the provided array always has the correct structure and has numerical indexes. But I would strongly recommend to not doing so, as good error checking can help you when bugs occur.

Performance wise this shouldn't be too bad. The many if statements when checking for errors are somewhat slow, but should be negligible. As far as I know the for loop doesn't operate on a copy of the provided array as foreach otherwise would. This is only a concern if you are having huge arrays. If this is the case I would strongly recommend using an iterator.

Regarding performance. Premature optimization is almost always not the answer. I would suggest you write SOLID code. Then when you are done you can profile your application and look for the performance heavy blocks. Remember that if your application relies on a database the biggest performance gains are properly in writing highly optimized SQL queries. Of course there are exceptions. If this function is used extensively throughout your code it's always good to think about optimization.

Happy coding!

 
 

Relacionados problema

4  Jerarquía de juego de clase simple con detección de colisiones  ( Simple class game hierarchy with collision detection ) 
Estoy tratando de hacer la transición de la fase de "entender cómo funciona" cómo funciona "de las características independientes". Más código 'complejo' que ...

6  Detección / resolución 2D de colisión de plataformas  ( 2d platformer collision detection resolution ) 
Estoy trabajando en un juego de plataformas basado en azulejos 2D y esperaba que alguien revisara mi detección de colisiones. Solo he incluido la comprobación...

2  Comprobando si una bala ha golpeado un invasor de espacio  ( Checking whether a bullet has hit a space invader ) 
Acabo de terminar (casi) un juego de invasores espaciales en Javascript. Tengo algunos insectos para eliminar el camino, pero mientras quería preguntar cómo p...

32  Rectángulos superpuestos  ( Overlapping rectangles ) 
Recibí la siguiente pregunta en una entrevista técnica hoy (para una posición DEVOPS / SRE): Escribe una función que devuelve verdadera si los dos rectángu...

10  Diseño de física con detección de colisiones utilizando SFML  ( Design of physics with collision detection using sfml ) 
Descubrí que en Visual Studio 2012, es posible crear un proyecto de SFML fácilmente con una plantilla. No soy un programador de C # experimentado. Por lo tant...

3  Algoritmo de detección de intersección  ( Intersection detection algorithm ) 
Este es un algoritmo de detección de intersección que desarrollé como un método alternativo para el desarrollado para mis cursos. No publicaré algunas de las ...

4  Ray → Plano y Ray → Intersección Quad  ( Ray%e2%86%92plane and ray%e2%86%92quad intersection ) 
Esto verifica la intersección entre un 123451 y un 123452 y entre un 99887776655443313 y un 99887766555443114 (en 3d): 123455 Por favor, analice...

8  Dibujo de lona / animación  ( Canvas drawing animation ) 
Estoy tratando de aprender a escribir JavaScript bueno, limpio y eficiente. Me considero un novicio, en el mejor de los casos, en JavaScript. Se aprecian cual...

1  Más JS AI causa un movimiento AI más lento en el lienzo HTML  ( More js ai causes slower ai movement in html canvas ) 
Tengo un pequeño juego simple con un personaje como el jugador y cuatro personajes enemigos. Creé un AI muy básico, que se mueve hacia el jugador cuando el ju...

1  Juego de ruptura en js  ( Breakout like game in js ) 
He hecho un pequeño juego de ruptura, hasta ahora con un nivel. Mi plan es ampliarlo para que tenga un editor de nivel, pero por ahora quería asegurarme de qu...




© 2022 respuesta.top Reservados todos los derechos. Centro de preguntas y respuestas reservados todos los derechos