Foros del Web » Programando para Internet » PHP »

Asociación bidireccional de string

Estas en el tema de Asociación bidireccional de string en el foro de PHP en Foros del Web. Hola gente que tal? Los consulto por un problema que tengo que no se me ocurre como resolver, tengo una posible solución pero que no ...
  #1 (permalink)  
Antiguo 17/10/2014, 14:53
Avatar de NSD
NSD
Colaborador
 
Fecha de Ingreso: mayo-2012
Ubicación: Somewhere
Mensajes: 1.332
Antigüedad: 12 años, 6 meses
Puntos: 320
Asociación bidireccional de string

Hola gente que tal?

Los consulto por un problema que tengo que no se me ocurre como resolver, tengo una posible solución pero que no me convence.

Lo que necesito es hacer una asociación bidireccional entre dos string, por ejemplo:

Dirección 1:
Humano -> Perro
Gato -> Raton
Vaca -> Queso

Direccion 2:
Perro -> Humano
Raton -> Gato
Queso -> Vaca

Lo que quiero hacer es una función que reciba la dirección y el valor de origen y devuelva el de destino, la posible solución que se me ocurrió es esta:
Código PHP:
Ver original
  1. <?php
  2. function bi_direccional($clave, $es_clave = true)
  3.     {
  4.         $asociaciones = [];
  5.         $asociaciones["humano"] = "perro";
  6.         $asociaciones["gato"] = "raton";
  7.         $asociaciones["vaca"] = "queso";
  8.        
  9.         if($es_clave)
  10.             return $asociaciones[$clave];
  11.         else
  12.             return array_search($clave, $asociaciones);
  13.     }

La cual funciona, pero el problema es que levanta a memoria todo el array, y este va a tener varios miles de elementos con lo cual el consumo de memoria va a ser grande.

Asi que pense otra solucion:
Código PHP:
Ver original
  1. function bi_direccional($clave, $es_clave = true)
  2.     {
  3.         if($es_clave)
  4.         {
  5.             switch($clave)
  6.             {
  7.                 case "humano" : $valor = "perro"; break;
  8.                 case "gato" : $valor = "raton"; break;
  9.                 case "vaca" : $valor = "queso"; break;        
  10.             }        
  11.         }
  12.         else
  13.         {
  14.             switch($clave)
  15.             {
  16.                 case "perro" : $valor = "humano"; break;
  17.                 case "raton" : $valor = "gato"; break;
  18.                 case "queso" : $valor = "vaca"; break;        
  19.             }
  20.         }
  21.         return $valor;
  22.     }

Pero que problema, esta no consume memoria pero tengo que escribir dos veces el switch y como son muchos valores tampoco me sirve.

Cabe destacar que todos estos valores los escribo a mano en script, son estáticos y no proceden de ninguna base de datos.

¿Se les ocurre alguna otra forma de solucionar el inconveniente?
__________________
Maratón de desafíos PHP Junio - Agosto 2015 en FDW | Reglamento - Desafios

Última edición por NSD; 17/10/2014 a las 16:11
  #2 (permalink)  
Antiguo 17/10/2014, 15:40
Avatar de pateketrueke
Modernizr
 
Fecha de Ingreso: abril-2008
Ubicación: Mexihco-Tenochtitlan
Mensajes: 26.399
Antigüedad: 16 años, 7 meses
Puntos: 2534
Respuesta: Asociación bidireccional de string

Caray, usa un array y ya, ¿para qué te complicas?

¿Qué es más molesto para ti?

a) Miles de elementos en un array, que según tu "consume más memoria" y es cierto, pero no por eso es malo.

b) Miles de condiciones lógicas, escrita una a una, realmente malo a mi parecer.

Ahora piensa, si tuvieras los datos en algún lado, ¿sería mejor?

¿Por qué necesitas meterlos a mano?

¿Por qué no usar una BD?

¿O un archivo JSON?

Piensa de nuevo las cosas: los arrays están perfectamente diseñados para acceder mediante su índice, o bien, la optimización de array_search() es buena.

En comparación, miles de condiciones una tras otra no sufren ningún tipo de optimización, son tan salvajes como escribir en ensamblador.

¿Y si usas alguna clase de SPL que esté mejor optimizada para arrays?

No sé, no entiendo por qué ahogarse en un vaso de agua.
__________________
Y U NO RTFM? щ(ºдºщ)

No atiendo por MP nada que no sea personal.
  #3 (permalink)  
Antiguo 17/10/2014, 16:09
Avatar de NSD
NSD
Colaborador
 
Fecha de Ingreso: mayo-2012
Ubicación: Somewhere
Mensajes: 1.332
Antigüedad: 12 años, 6 meses
Puntos: 320
Respuesta: Asociación bidireccional de string

Hola, @pateketrueke, intentare responder todas tus preguntas:

Cita:
Caray, usa un array y ya, ¿para qué te complicas?
No me agrada la idea de levantar a memoria miles de elementos si solo voy a usar 5, es matar moscas a cañonazos.

Cita:
¿Qué es más molesto para ti?

a) Miles de elementos en un array, que según tu "consume más memoria" y es cierto, pero no por eso es malo.

b) Miles de condiciones lógicas, escrita una a una, realmente malo a mi parecer.
Lo mas molesto para mi es consumir muchos mas recursos de los que necesito. Si, es mas cómodo un array. Si es mas tedioso condicionales anidados. Pero la opcion tediosa consume menos recursos.

Cita:
Ahora piensa, si tuvieras los datos en algún lado, ¿sería mejor?
Si los tuviera en "algún lado" que supongo de refieres a una BD, no me estaría planteando este problema, se los pediría a la base de datos y listo.

Cita:
¿Por qué necesitas meterlos a mano?
Son constantes de configuración y mapeos, son propios de cada sistema por lo que no hay mucha reusabilidad, mi prioridad es que consuma pocos recursos y que funcione rápido, puedo prescindir de claridad siempre y cuando no se vuelva inmantenible, como pasaría en el caso de tener dos switch enormes con los mismos datos.

Cita:
¿Por qué no usar una BD?
Porque es algo que necesito que este dentro de php, no me aporta ninguna ventaja meterlos en una base de datos aparte de comodidad. Dicho de otra forma, no tengo ningún problema que no pueda solucionar sin una base de datos, así que no la necesito.

Cita:
¿O un archivo JSON?
Si lo guardo en json es lo mismo que guardarlo en un array, tendré que levantarlo todo y tendre un array o un objeto enorme en memoria del cual solo usare un par de propiedades.

Cita:
Piensa de nuevo las cosas: los arrays están perfectamente diseñados para acceder mediante su índice, o bien, la optimización de array_search() es buena.

En comparación, miles de condiciones una tras otra no sufren ningún tipo de optimización, son tan salvajes como escribir en ensamblador.
El ensamblador es sumamente rápido y eficiente, de hecho, es lo mas rápido y eficiente después del binario.
Te equivocas con lo de que no hay ninguna optimizacion, una estructura switch es optimizada internamente con algoritmos de busqueda, similares a los que se usan en array_search (si es que no son los mismos).

Cita:
¿Y si usas alguna clase de SPL que esté mejor optimizada para arrays?
Quisiera evitar el uso de arrays, con o sin SPL, no obstante las clases que encontre agregan funcionalidades que no me sirven para este problema.

Cita:
No sé, no entiendo por qué ahogarse en un vaso de agua.
Solo busco la forma mas eficiente de solucionar un problema, no la mas cómoda.
Si lo necesitara ya, implementaría arrays ya que no conozco aun otra solucion alternativa, pero como puedo esperar abri este tema a ver si alguien se le ocurre otra variante.

Gracias por el interes.

Edito:

Se me ocurre esta tercer solución:
Código PHP:
Ver original
  1. <?php
  2.  function bi_direccional($clave, $es_clave = true)
  3.     {
  4.         switch($clave)
  5.         {
  6.             case "humano" :
  7.             case "perro" :
  8.                 $valor = ($es_clave ? "perro" : "humano");
  9.             break;
  10.             case "gato" :
  11.             case "raton" :
  12.                 $valor = ($es_clave ? "raton" : "gato");
  13.             break;
  14.             case "vaca" :
  15.             case "queso" :
  16.                 $valor = ($es_clave ? "queso" : "vaca");
  17.             break;
  18.         }
  19.         return $valor;
  20.     }

Es mucho mejor la que segunda ya que hay un solo switch pero igual sigue siendo compleja.
__________________
Maratón de desafíos PHP Junio - Agosto 2015 en FDW | Reglamento - Desafios

Última edición por NSD; 17/10/2014 a las 16:17
  #4 (permalink)  
Antiguo 17/10/2014, 16:26
Avatar de pateketrueke
Modernizr
 
Fecha de Ingreso: abril-2008
Ubicación: Mexihco-Tenochtitlan
Mensajes: 26.399
Antigüedad: 16 años, 7 meses
Puntos: 2534
Respuesta: Asociación bidireccional de string

Entiendo tu punto, lo que se me ocurre entonces es lo siguiente:

Primero, tener los datos en otro formato es más cómodo siempre, y como has dicho que es configuración me parece ideal que sea así, ya sea usando JSON/YAML/INI o algo similar.

Luego, lo que si es comprensible es la necesidad de no cargar todo en memoria cada ves, y también entiendo que el código es mucho más rápido para esto.

Entonces, ¿por qué no pre-generar el código basado en switch/condicionales a partir e la estructura de datos?

En resumen: un código estático es mucho más eficiente que uno dinámico.

Solución: programa algo que convierta tus datos en código.
__________________
Y U NO RTFM? щ(ºдºщ)

No atiendo por MP nada que no sea personal.
  #5 (permalink)  
Antiguo 17/10/2014, 17:50
Avatar de NSD
NSD
Colaborador
 
Fecha de Ingreso: mayo-2012
Ubicación: Somewhere
Mensajes: 1.332
Antigüedad: 12 años, 6 meses
Puntos: 320
Respuesta: Asociación bidireccional de string

Cita:
Solución: programa algo que convierta tus datos en código.
Interesante propuesta, ¿como te parece mejor, que sea un script php el que haga esa tarea o que sea un ejecutable (en otro lenguaje obvio)?
__________________
Maratón de desafíos PHP Junio - Agosto 2015 en FDW | Reglamento - Desafios
  #6 (permalink)  
Antiguo 17/10/2014, 23:06
Avatar de pateketrueke
Modernizr
 
Fecha de Ingreso: abril-2008
Ubicación: Mexihco-Tenochtitlan
Mensajes: 26.399
Antigüedad: 16 años, 7 meses
Puntos: 2534
Respuesta: Asociación bidireccional de string

Cualquier cosa que domines está bien, como sea es un tarea que ejecutarás pocas veces.
__________________
Y U NO RTFM? щ(ºдºщ)

No atiendo por MP nada que no sea personal.
  #7 (permalink)  
Antiguo 18/10/2014, 00:02
Avatar de NSD
NSD
Colaborador
 
Fecha de Ingreso: mayo-2012
Ubicación: Somewhere
Mensajes: 1.332
Antigüedad: 12 años, 6 meses
Puntos: 320
Respuesta: Asociación bidireccional de string

Muy bien muchas gracias por la ayuda, dejo abierto el tema por si alguien tiene otra idea diferente, o se le ocurre otra forma de plantear el código, pero creo que tu propuesta es bastante buena.

Saludos.
__________________
Maratón de desafíos PHP Junio - Agosto 2015 en FDW | Reglamento - Desafios

Etiquetas: asociación, string
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 11:08.