Używanie usort w php z prywatną funkcją klasy

119

ok używanie usort z funkcją nie jest takie skomplikowane

To właśnie miałem wcześniej w moim kodzie liniowym

function merchantSort($a,$b){
    return ....// stuff;
}

$array = array('..','..','..');

sortować, po prostu robię

usort($array,"merchantSort");

Teraz aktualizujemy kod i usuwamy wszystkie funkcje globalne i umieszczamy je w odpowiednich miejscach. Teraz cały kod jest w klasie i nie mogę dowiedzieć się, jak użyć funkcji usort do sortowania tablicy z parametrem, który jest metodą obiektu zamiast prostej funkcji

class ClassName {
   ...

   private function merchantSort($a,$b) {
       return ...// the sort
   }

   public function doSomeWork() {
   ...
       $array = $this->someThingThatReturnAnArray();
       usort($array,'$this->merchantSort'); // ??? this is the part i can't figure out
   ...

   }
}

Pytanie brzmi, jak wywołać metodę obiektu wewnątrz funkcji usort ()

Ibu
źródło

Odpowiedzi:

228

Ustaw funkcję sortowania jako statyczną:

private static function merchantSort($a,$b) {
       return ...// the sort
}

I użyj tablicy dla drugiego parametru:

$array = $this->someThingThatReturnAnArray();
usort($array, array('ClassName','merchantSort'));
Demian Brecht
źródło
2
To jest świetne! Chciałbym również zwrócić uwagę, że funkcja sortowania nie musi być deklarowana niejawnie jako metoda statyczna; jak to nadal działa bez :)
Jimbo
@Jimbo - to ma sens, więc funkcja prywatna może używać instancji i zmiennych klas. Tak, to jest świetne! Zobacz także odpowiedź @deceze, gdzie możesz przejść $this(neato).
Ben
5
Jeśli uczynisz funkcję statyczną (co powinieneś), możesz po prostu napisać usort($array, 'ClassName:merchantSort'), prawda?
krakać
8
Człowieku, to wydaje się dziwnym sposobem na zrobienie tego. Och, PHP, jak my Cię kochamy.
dudewad
12
@MarcoW., Myślę, że między ClassName a merchantSort brakuje drugiego znaku „:”. Ponadto, jeśli funkcja jest używana w tej samej klasie, przetestowałem ją z 'self::merchantSort'i działa.
Pere
21

Musisz zdać $thisnp:usort( $myArray, array( $this, 'mySort' ) );

Pełny przykład:

class SimpleClass
{                       
    function getArray( $a ) {       
        usort( $a, array( $this, 'nameSort' ) ); // pass $this for scope
        return $a;
    }                 

    private function nameSort( $a, $b )
    {
        return strcmp( $a, $b );
    }              

}

$a = ['c','a','b']; 
$sc = new SimpleClass();
print_r( $sc->getArray( $a ) );
Justin
źródło
Druga sekcja jest teraz znacznie lepsza. Jednak w pierwszym przykładzie nadal brakuje znaku „)”.
Codescribblr
5

W tym przykładzie sortuję według pola wewnątrz tablicy o nazwie AverageVote.

Możesz dołączyć metodę do wywołania, co oznacza, że ​​nie masz już problemu z zakresem klasy, na przykład ...

        usort($firstArray, function ($a, $b) {
           if ($a['AverageVote'] == $b['AverageVote']) {
               return 0;
           }

           return ($a['AverageVote'] < $b['AverageVote']) ? -1 : 1;
        });
James K.
źródło
1
Ma to sens tylko wtedy, gdy używasz tej funkcji tylko w tym jednym rodzaju. W wielu przypadkach to samo porównanie jest używane w wielu miejscach.
jedwab
1
To było idealne do tego, co musiałem zrobić. Dzięki!
Christopher Smit
3

W klasie modelu Laravel (5.6) nazwałem to w ten sposób, obie metody są public static, używają php 7.2 w systemie Windows 64 bit.

public static function usortCalledFrom() 

public static function myFunction()

Zadzwoniłem do usortCalledFrom () w ten sposób

usort($array,"static::myFunction")

Żadne z nich nie działało

usort($array,"MyClass::myFunction")
usort($array, array("MyClass","myFunction")
hrnsky
źródło
static::zamiast nazwy klasy jest to, czego potrzebowałem, dzięki za wspomnienie.
Szczery