質問
PHP でオブジェクトを並べ替えるエレガントな方法は何ですか?これと同じようなことをぜひ実現したいと思っています。
$sortedObjectArary = sort($unsortedObjectArray, $Object->weight);
基本的には、並べ替える配列と並べ替えるフィールドを指定します。多次元配列のソートを調べてみたところ、何か役立つものがあるかもしれませんが、エレガントで明白なものは見つかりませんでした。
解決
マニュアルからほぼそのまま:
function compare_weights($a, $b) {
if($a->weight == $b->weight) {
return 0;
}
return ($a->weight < $b->weight) ? -1 : 1;
}
usort($unsortedObjectArray, 'compare_weights');
オブジェクト自体をソートできるようにしたい場合は、こちらの例 3 を参照してください。 http://php.net/usort
他のヒント
PHP の場合 >= 5.3
function osort(&$array, $prop)
{
usort($array, function($a, $b) use ($prop) {
return $a->$prop > $b->$prop ? 1 : -1;
});
}
これは匿名関数/クロージャを使用することに注意してください。これに関する php ドキュメントを確認すると役立つかもしれません。
そのレベルの制御が必要な場合は、並べ替えているクラスに並べ替え動作を組み込むこともできます。
class thingy
{
public $prop1;
public $prop2;
static $sortKey;
public function __construct( $prop1, $prop2 )
{
$this->prop1 = $prop1;
$this->prop2 = $prop2;
}
public static function sorter( $a, $b )
{
return strcasecmp( $a->{self::$sortKey}, $b->{self::$sortKey} );
}
public static function sortByProp( &$collection, $prop )
{
self::$sortKey = $prop;
usort( $collection, array( __CLASS__, 'sorter' ) );
}
}
$thingies = array(
new thingy( 'red', 'blue' )
, new thingy( 'apple', 'orange' )
, new thingy( 'black', 'white' )
, new thingy( 'democrat', 'republican' )
);
print_r( $thingies );
thingy::sortByProp( $thingies, 'prop1' );
print_r( $thingies );
thingy::sortByProp( $thingies, 'prop2' );
print_r( $thingies );
その比較関数については、次のようにするだけです。
function cmp( $a, $b )
{
return $b->weight - $a->weight;
}
usort 関数 (http://uk.php.net/manual/en/function.usort.php) あなたの友だちです。何かのようなもの...
function objectWeightSort($lhs, $rhs)
{
if ($lhs->weight == $rhs->weight)
return 0;
if ($lhs->weight > $rhs->weight)
return 1;
return -1;
}
usort($unsortedObjectArray, "objectWeightSort");
配列キーは失われることに注意してください。
を使用できます usort() 関数を使用して独自の比較関数を作成します。
$sortedObjectArray = usort($unsortedObjectArray, 'sort_by_weight');
function sort_by_weight($a, $b) {
if ($a->weight == $b->weight) {
return 0;
} else if ($a->weight < $b->weight) {
return -1;
} else {
return 1;
}
}
解決しようとしている問題によっては、SPL インターフェイスが役立つ場合もあります。たとえば、ArrayAccess インターフェイスを実装すると、配列のようにクラスにアクセスできるようになります。また、SeekableIterator インターフェイスを実装すると、配列のようにオブジェクトをループできるようになります。このようにして、オブジェクトを単純な配列であるかのように並べ替えることができ、特定のキーに対して返される値を完全に制御できます。
詳細については:
function PHPArrayObjectSorter($array,$sortBy,$direction='asc')
{
$sortedArray=array();
$tmpArray=array();
foreach($this->$array as $obj)
{
$tmpArray[]=$obj->$sortBy;
}
if($direction=='asc'){
asort($tmpArray);
}else{
arsort($tmpArray);
}
foreach($tmpArray as $k=>$tmp){
$sortedArray[]=$array[$k];
}
return $sortedArray;
}
例 =>
$myAscSortedArrayObject=PHPArrayObjectSorter($unsortedarray,$totalMarks,'asc');
$myDescSortedArrayObject=PHPArrayObjectSorter($unsortedarray,$totalMarks,'desc');
投稿したものとほぼ同じコードを使用できます 並べ替えられた からの関数 Nspl:
use function \nspl\a\sorted;
use function \nspl\op\propertyGetter;
use function \nspl\op\methodCaller;
// Sort by property value
$sortedByWeight = sorted($objects, propertyGetter('weight'));
// Or sort by result of method call
$sortedByWeight = sorted($objects, methodCaller('getWeight'));
PHP のラムダ スタイル関数の (恐ろしい) 範囲をすべて探索したい場合は、以下を参照してください。http://docs.php.net/manual/en/function.create-function.php