我有以下数组:
Array
(
[0] => stdClass Object
(
[timestamp] => 1
[id] => 10
)
[1] => stdClass Object
(
[timestamp] => 123
[id] => 1
)
[2] => stdClass Object
(
[timestamp] => 123
[id] => 2
)
)
我目前正在使用以下代码按时间戳属性对数组进行排序:
function sort_comments_by_timestamp(&$comments, $prop)
{
usort($comments, function($a, $b) use ($prop) {
return $a->$prop < $b->$prop ? 1 : -1;
});
}
如果时间戳相同,我怎样才能按id
降序来排序?
答案 0 :(得分:18)
建议使用$ props
发送数组function sort_comments_by_timestamp(&$comments, $props)
{
usort($comments, function($a, $b) use ($props) {
if($a->$props[0] == $b->$props[0])
return $a->$props[1] < $b->$props[1] ? 1 : -1;
return $a->$props[0] < $b->$props[0] ? 1 : -1;
});
}
然后用
调用它sort_comments_by_timestamp($unsorted_array,array("timestamp","id"));
如果你想让它与X个$ props一起工作,你可以在usort中创建一个循环,总是将一个属性与数组中的前一个属性进行比较,如下所示:
function sort_comments_by_timestamp(&$comments, $props)
{
usort($comments, function($a, $b) use ($props) {
for($i = 1; $i < count($props); $i++) {
if($a->$props[$i-1] == $b->$props[$i-1])
return $a->$props[$i] < $b->$props[$i] ? 1 : -1;
}
return $a->$props[0] < $b->$props[0] ? 1 : -1;
});
}
干杯!
答案 1 :(得分:3)
function sort_comments_by_timestamp(&$comments, $prop)
{
usort($comments, function($a, $b) use ($prop) {
if ($a->$prop == $b->$prop)
return $b->id - $a->id;
else
return $a->$prop < $b->$prop ? 1 : -1;
});
}
以上按$prop
参数排序,然后按id
排序。
答案 2 :(得分:3)
您可以使用ouzo goodies(我知道您已经听说过:P)。
$result = Arrays::sort($array,
Comparator::compound(
Comparator::compareBy('timestamp'),
Comparator::compareBy('id')
)
);
答案 3 :(得分:2)
$result = -1;
if ($a->timestamp < $b->timestamp) {
$result = 1;
} else if ($a->timestamp === $b->timestamp) {
if ($a->id < $b->id) $result = 1;
}
return $result;
把它放在usort闭包中。您还可以删除$ prop参数和use ($prop)
部分。
答案 4 :(得分:2)
我知道这是一个相当陈旧的问题但是没有找到很多信息,当你想要按多个属性进行排序时,例如mySQL ORDERBY 这样做是来自个人的功能框架
选项1:订单( $ key,$ direction =&#39; asc&#39; ),其中$ key是对象的属性,$ direction是&#39; asc&#39 ;或者&#39; desc&#39;
选项2:订单(数组($ key =&gt; $ direction,$ key =&gt; $ direction)) 这与选项1类似,但是当2个对象具有相同的$ key值时,将使用传递的数组中的第二个排序选项。
public function order($arr, $key=null, $direction='ASC'){
if(!is_string($key) && !is_array($key))
throw new InvalidArgumentException("order() expects the first parameter to be a valid key or array");
$props = array();
if(is_string($key)) {
$props[$key] = strtolower($direction) == 'asc' ? 1 : -1;
}else{
$i = count($key);
foreach($key as $k => $dir){
$props[$k] = strtolower($dir) == 'asc' ? $i : -($i);
$i--;
}
}
usort($arr, function($a, $b) use ($props){
foreach( $props as $key => $val ){
if( $a->$key == $b->$key ) continue;
return $a->$key > $b->$key ? $val : -($val);
}
return 0;
});
return $arr;
}
答案 5 :(得分:1)
function compare_city($a, $b)
{
// sort by state
$retval = strnatcmp($a->state, $b->state);
// if identical, sort by city
if(!$retval) $retval = strnatcmp($a->city, $b->city);
return $retval;
}
// sort alphabetically by state and city
usort($sortable, __NAMESPACE__ . '\compare_city');
这个功能对我有用!答案发现于:Sorting SimpleXMLElement Object arrays
答案 6 :(得分:1)
被接受的答案具有循环变体,该变体将不总是有效。
if($a->$props[$i-1] == $b->$props[$i-1])
return $a->$props[$i] < $b->$props[$i] ? 1 : -1;
obj1 prop1:foo,prop2:bar,prop3:test
obj2 prop1:foo,prop2:bar,prop3:苹果
在$ i = 1时,第一个比较为真,并且bar不小于bar,它将返回-1,而不是继续执行循环以求prop3。
仅供参考。
我有一个变体,它也可以指示方向,因此每个属性也可以分别使用-1和1进行升序或降序排序。
function sortByProps(&$anArray, $props) {
usort($anArray, function($a, $b) use ($props) {
for($i = 0; $i < count($props); $i++) {
if( $a->{$props[$i][0]} < $b->{$props[$i][0]}) {
return $props[$i][1];
}
else if( $a->{$props[$i][0]} > $b->{$props[$i][0]}) {
return -1* $props[$i][1];
}
}
return 0;
});
}
sortByProps($someArray,(array(['name',-1],['address',-1],['occupation',-1],['favorite_food',-1])));
答案 7 :(得分:0)
按任意数量的标准排序。我总是忘记$ a - $ b是按升序还是降序排序。根据需要进行调整。
$comparatorSequence = array(
function($a, $b) {
return $a->timestamp - $b->timestamp;
}
, function($a, $b) {
return $a->id - $b->id;
}
);
usort($theArray, function($a, $b) use ($comparatorSequence) {
foreach ($comparatorSequence as $cmpFn) {
$diff = call_user_func($cmpFn, $a, $b);
if ($diff !== 0) {
return $diff;
}
}
return 0;
});