Sé que este es un hilo viejo, pero me encontré con otra instancia hoy que podrían beneficiarse de otro enfoque. Tuve un caso en el que quería usar una clave específica para poder resumir la función de soporte real. Esto llevó a encontrar una versión que utilizara una función de contenedor para devolver una función anónima utilizando la palabra de comando 'usar' para proporcionar el nombre de la clave utilizada para clasificar en mi clase. (en mi caso, es una clave en una propiedad en una clase [anidada] que está asignada a una de las propiedades de clase donde estoy haciendo la clasificación, es decir, estoy ordenando instancias basadas en una propiedad en una instancia de 'dimensiones' asignado a una propiedad de 'elementos' y quiere poder ordenarlos por ancho, alto, longitud o peso, por ejemplo). Luego de obtener su función para la devolución de llamada, sólo tiene que llamar a esta función derivador con el nombre clave que desea utilizar para ordenar el resultado:
/**
* list of items
*
* @var Item[]
*/
public $items;
/**
* @param string $key
* @return \Closure
*/
private static function keySort($key) {
return function ($ia, $ib) use ($key) {
if($ia->dimensions->$key == $ib->dimensions->$key) return 0;
return ($ia->dimensions->$key < $ib->dimensions->$key) ? -1 : 1;
};
}
/**
* return the list of items in the items array sorted by the value
* of the property specified by $key
*
* @param string $key
* @return Item[]
* @throws \Exception
*/
public function sortItemsByKey($key)
{
if(in_array($key, array('width', 'length', 'height', 'weight',))) {
return usort($this->items, static::keySort($key));
} else
throw new \Exception(__METHOD__ . ' invalid sort key!');
}
Esto permite que llame usando local, ya sea estática o auto ::: : (concebiblemente, podría incluso incluirlo como una función no estática en este caso, ya que lo único que me preocupa es obtener la llamada, pero se devuelve la función) Otro beneficio que pronto descubrí es que mi objeto de dimensiones también tiene algunos 'cálculos 'campos tales como circunferencia, volumen y peso dimensional. Pero un problema es que el peso dimensional varía dependiendo de si está enviando un artículo a nivel nacional o internacional, por lo que necesito decirle a mi función 'calculateDimensionalWeight' si debe usar el valor para envío internacional o no.Bueno, usando este método, puedo hacerlo simplemente pasando un parámetro adicional a la función de envoltura y agregando el parámetro adicional a las variables de uso. Puesto que también es necesario para asegurarse de que estos valores han sido calculados antes de hacer cualquier comparación, puedo provocar que en mi función basada en la clave:
/**
* @param string $key
* @param bool $intl // only used for dimensional weight
* @return \Closure
*/
private static function keySort($key,$intl=false) {
return function ($ia, $ib) use ($key,$intl) {
switch($key) {
case 'girth':
$ia->dimensions->calculateGirth();
$ib->dimensions->calculateGirth();
break;
case 'dimweight':
$ia->dimensions->calculateDimensionalWeight($intl);
$ib->dimensions->calculateDimensionalWeight($intl);
break;
case 'volume':
$ia->dimensions->calculateVolume();
$ib->dimensions->calculateVolume();
break;
}
if($ia->dimensions->$key == $ib->dimensions->$key) return 0;
return ($ia->dimensions->$key < $ib->dimensions->$key) ? -1 : 1;
};
}
/**
* return the list of items in the items array sorted by the value
*
* @param string $key
* @param bool $intl (only used for dimensional weight sorts on international shipments)
* @return Item[]
* @throws \Exception
*/
public function sortItemsByKey($key,$intl=false)
{
if(in_array($key, array('value','collect', 'width', 'length', 'height', 'weight', 'girth', 'dimweight', 'volume'))) {
return usort($this->items, static::keySort($key,$intl));
} else
throw new \Exception(__METHOD__ . ' invalid sort key!');
}
NOTA: el cálculo de los valores de esta manera crea por encima mientras todos menos el primero y los últimos elementos de cualquier lista se calcularán técnicamente dos veces, lo cual es redundante, pero en este caso mis listas no son largas y, en algunos casos, debo comparar dos elementos cuando hago bin-sorting, por lo que aún es preferible. Para conjuntos de datos grandes, probablemente sería más prudente calcular previamente valores externos al método de clasificación.
De alguna manera creo que te has perdido [esta respuesta] (http://stackoverflow.com/a/6054036/1229023) al buscar problemas similares, ¿no?) – raina77ow
Lo vio, pero el nombre de la clase no funcionó. $ esto lo hace. – Marinus
¿Hizo esta función estática antes de intentar llamarla con el nombre de clase? – raina77ow