Reputation: 24315
let's say I have an object, $obj
, that after this foreach()
loop:
foreach($obj as $row){
echo 'file_id:'.$row->file_id.'-name:'.$row->name.'<br>';
}
would look like this:
file_id:321-name:321-is-good
file_id:322-name:322-is-better
file_id:323-name:323-is-best
How can I sort $obj
such that I can choose what is the first echo
'd $row
? For example, if I plugged in 322
somewhere, the result would look like this:
file_id:322-name:322-is-better
file_id:323-name:323-is-best
file_id:321-name:321-is-good
and if I plugged in 323
:
file_id:323-name:323-is-best
file_id:321-name:321-is-good
file_id:322-name:322-is-better
I know it probably involves usort()
but I can't wrap my head around what needs to be done.
thoughts?
thanks, tim
Upvotes: 0
Views: 252
Reputation: 70510
Assuming you want to sort on file_id
at a specific start, appending what comes before, which is also sorted on file_id
:
$sort = '323';
usort($arr,function($a,$b) use ($sort) {
//normal sorting for low-ids after high-ids
if($a->file_id < $sort && $a->file_id < $sort){
return strcmp($a->file_id,$b->file_id);
}
//if only $a is smaller $a should be later
if($a->file_id < $sort) return 1;
//if only $b is smaller $a should be earlier
if($b->file_id < $sort) return -1;
//both above $sort, sort normally
return strcmp($a->file_id,$b->file_id);
});
Working example with an Object instead of a Array:
<?php
//build a test with arrays is easier;
$arr = new ArrayObject(array(
array('file_id' => '321','name' => '321 is good'),
array('file_id' => '322','name' => '322 is better'),
array('file_id' => '323','name' => '323 is best')));
//cast all to object for purposes of testing objects
foreach($arr as &$val) $val = (object)$val;
//when you used a reference _always_ unset... trust me on this one
unset($val);
$sort = '323';
// we define the callback separately because for this test we use it more then once
// don't pay much attention to the reference as &$sort, this is just to alter it in
// multiple tests, and should not be needed in the actual implementation.
$callback = function($a,$b) use (&$sort) {
//normal sorting for low-ids after high-ids
if($a->file_id < $sort && $b->file_id < $sort){ //$a & $b indeed, not $a twice ;)
return strcmp($a->file_id,$b->file_id);
}
//if only $a is smaller $a should be later
if($a->file_id < $sort) return 1;
//if only $b is smaller $a should be earlier
if($b->file_id < $sort) return -1;
//both above $sort, sort normally
return strcmp($a->file_id,$b->file_id);
};
//322 first:
$sort='322';
$arr->uasort($callback);
var_dump($arr);
//323 first:
$sort='323';
$arr->uasort($callback);
var_dump($arr);
//321 again first:
$sort='321';
$arr->uasort($callback);
var_dump($arr);
//non-existing:
$sort='400';
$arr->uasort($callback);
var_dump($arr);
object(ArrayObject)#1 (1) {
["storage":"ArrayObject":private]=>
array(3) {
[1]=>
object(stdClass)#5 (2) {
["file_id"]=>
string(3) "322"
["name"]=>
string(13) "322 is better"
}
[2]=>
object(stdClass)#6 (2) {
["file_id"]=>
string(3) "323"
["name"]=>
string(11) "323 is best"
}
[0]=>
object(stdClass)#4 (2) {
["file_id"]=>
string(3) "321"
["name"]=>
string(11) "321 is good"
}
}
}
object(ArrayObject)#1 (1) {
["storage":"ArrayObject":private]=>
array(3) {
[2]=>
object(stdClass)#6 (2) {
["file_id"]=>
string(3) "323"
["name"]=>
string(11) "323 is best"
}
[0]=>
object(stdClass)#4 (2) {
["file_id"]=>
string(3) "321"
["name"]=>
string(11) "321 is good"
}
[1]=>
object(stdClass)#5 (2) {
["file_id"]=>
string(3) "322"
["name"]=>
string(13) "322 is better"
}
}
}
object(ArrayObject)#1 (1) {
["storage":"ArrayObject":private]=>
array(3) {
[0]=>
object(stdClass)#4 (2) {
["file_id"]=>
string(3) "321"
["name"]=>
string(11) "321 is good"
}
[1]=>
object(stdClass)#5 (2) {
["file_id"]=>
string(3) "322"
["name"]=>
string(13) "322 is better"
}
[2]=>
object(stdClass)#6 (2) {
["file_id"]=>
string(3) "323"
["name"]=>
string(11) "323 is best"
}
}
}
object(ArrayObject)#1 (1) {
["storage":"ArrayObject":private]=>
array(3) {
[0]=>
object(stdClass)#4 (2) {
["file_id"]=>
string(3) "321"
["name"]=>
string(11) "321 is good"
}
[1]=>
object(stdClass)#5 (2) {
["file_id"]=>
string(3) "322"
["name"]=>
string(13) "322 is better"
}
[2]=>
object(stdClass)#6 (2) {
["file_id"]=>
string(3) "323"
["name"]=>
string(11) "323 is best"
}
}
}
Upvotes: 2