ursus contionabundo: Oder ... nach Rolfs Idee

Beitrag lesen

nein, sorry, du hattest recht. Gesucht ist Bar, Foo, bar, foo.

Sicher bin ich mir da gar nicht. Die Aufgabestellung ist durchaus mehrdeutig und Rekneh hat sich im Forum nicht gemeldet um das klarzustellen.

Trotzdem verstehe ich noch nicht, warum 1==($a<=>$b) die Aufgabenstellung löst.

Da bin ich bei Dir. Auch meine Tests lassen mich mit dem Rätsel zurück, WARUM das geht. (Insofern kann ich Vorgehen nicht ernsthaft empfehlen!) Auch die Ausgaben geben mir keine wirkliche Hilfe.

<?php

$final_array[]['score']='foo';
$final_array[]['score']='quirx';
$final_array[]['score']='Quirx';
$final_array[]['score']='Bar';
$final_array[]['score']='bar';
$final_array[]['score']='Foo';

usort( $final_array, function( $a, $b ) {
	echo 
	    '"' . $a['score'] . '" <=> "' . $b['score'] . '" : '
	    . ( $a['score'] <=> $b['score'] )  
		  . ' => ' 
		  . (int)( 1 == ( $a['score'] <=> $b['score'] ) ) 
		  . PHP_EOL;
    return (int)1 == ( $a['score'] <=> $b['score'] );
} );

print_r( $final_array );
"foo" <=> "quirx" : -1 => 0
"quirx" <=> "Quirx" : 1 => 1
"foo" <=> "Quirx" : 1 => 1
"quirx" <=> "Bar" : 1 => 1
"foo" <=> "Bar" : 1 => 1
"Quirx" <=> "Bar" : 1 => 1
"quirx" <=> "bar" : 1 => 1
"foo" <=> "bar" : 1 => 1
"Quirx" <=> "bar" : -1 => 0
"quirx" <=> "Foo" : 1 => 1
"foo" <=> "Foo" : 1 => 1
"bar" <=> "Foo" : 1 => 1
"Quirx" <=> "Foo" : 1 => 1
"Bar" <=> "Foo" : -1 => 0
Array
(
    [0] => Array
        (
            [score] => Bar
        )

    [1] => Array
        (
            [score] => Foo
        )

    [2] => Array
        (
            [score] => Quirx
        )

    [3] => Array
        (
            [score] => bar
        )

    [4] => Array
        (
            [score] => foo
        )

    [5] => Array
        (
            [score] => quirx
        )

)

Ich habe keinen Fehler provozieren können. Auch mit dem ganz großen Test nicht:

<?php

$ar     = [ 'foo', 'qix', 'Bar', 'Qix', 'bar', 'Foo' ];
$sorted = [ 'Bar', 'Foo', 'Qix', 'bar', 'foo', 'qix' ];

$z=0;
while ( $z < 1000 ) {
	shuffle( $ar ); # Array oft genug mixen statt nachdenken...
	if ( myUsort( $ar ) != $sorted ) {
	   print_r( $ar );
	   break;
	}
	echo $z++ . ' ';
}

function myUsort( $ar ) {
	usort( $ar, function( $a, $b ) {
		/*
		echo 
			'"' . $a . '" <=> "' . $b . '" : '
			. ( $a <=> $b )  
			  . ' => ' 
			  . (int)( 1 == ( $a <=> $b ) ) 
			  . PHP_EOL;
	    */
		return (int)1 == ( $a <=> $b );
	} );
	return $ar;
}

Theoretisch sorgt usort nur dann für eine Umsortierung, wenn das Return der aufgerufenen Funktion 1 ist. Bei 0 und -1 macht usort gar nichts. Ich hab das mit allem möglichen Zeug probiert:

<?php
$or = [ "Bar", "foo" ];

$ar = $or;
usort( $ar, function( $a, $b ) {
   echo "$a, $b" . PHP_EOL;
   return -1;
} );
echo '-1: ' . implode (', ', $ar) . PHP_EOL . PHP_EOL;

# Bar, foo
# -1: Bar, foo

$ar = $or;
usort( $ar, function( $a, $b ) {
   echo "$a, $b" . PHP_EOL;
   return 0;
} );
echo ' 0: ' . implode (', ', $ar) . PHP_EOL . PHP_EOL;

# Bar, foo
# 0: Bar, foo

$ar = $or;
usort( $ar, function( $a, $b ) {
   echo "$a, $b" . PHP_EOL;
   return 1;
} );
echo ' 1: ' . implode (', ', $ar) . PHP_EOL . PHP_EOL;

# Bar, foo
# 1: foo, Bar

So lange ich von einem klügeren nichts besseres erfahre (die Dokumentation sagt gar nichts!) Denke ich: "Hm. Entweder ein Bug oder ein Easteregg.". Ich habe auch schon erfolgsfrei nach "usort" in C und CPP gesucht, weil PHP manche Standard-Funktionen von C/CPP nur zu "wrappen" scheint.