我有这样的JSON:
{
"class": {
"type": "major",
"order": "1"
},
"number": {
"type": "date",
"order": "5"
},
"amount": {
"type": "date",
"order": "3"
},
}
我需要将其转换为PHP数组并基于order
字段进行排序。
如果数字相同,则订单应保持不变。
编辑:
此外,如果某些元素没有order
,那么它们应该位于底部
答案 0 :(得分:4)
您可以使用json_decode()
将其转换为PHP数组。然后,您需要编写usort()
的稳定实现来对值进行排序。像这样:
function stableSort(array $array) {
// turn the input array into something we can more easily manipulate
$lookup = array();
$i = 0;
foreach($array as $key => $value) {
$lookup[] = array(
'position' => $i++,
'key' => $key,
'value' => $value);
}
usort($lookup, function(array $a, array $b) {
if(!isset($a['value']['order'])) {
if(!isset($b['value']['order'])) {
return $a['position'] > $b['position'];
}
return 1;
}
if(!isset($b['value']['order'])) {
return -1;
}
if($a['value']['order'] == $b['value']['order']) {
return $a['position'] > $b['position'];
}
return $a['value']['order'] > $b['value']['order'] ? 1 : -1;
});
// recreate the original array
$sorted = array();
foreach($lookup as $element) {
$sorted[$element['key']] = $element['value'];
}
return $sorted;
}
$array = json_decode($json, true);
$sorted = stableSort($array);
我们永远不会从比较函数中返回0,因为这会破坏稳定排序的保证。前两个if
语句用于处理一个或两个输入中不存在order
键的情况。
答案 1 :(得分:0)
你应该将json解码为数组,然后使用usort对数组进行排序:
$data = '{
"class": {
"type": "major",
"order": "1"
},
"number": {
"type": "date",
"order": "5"
},
"amount": {
"type": "date",
"order": "3"
}
}';
$array = json_decode($data, true);
usort($array, function ($left, $right) {
if ($left['order'] == $right['order']) {
return 0;
}
return $left['order'] < $right['order'] ? -1 : 1;
});
var_dump($array);
为了保证稳定的排序,您需要在排序之前对元素进行索引,并在比较“相等”元素时使用该索引。我还添加了一些条件来将具有空顺序的元素移动到底部(但是保留了对主序列的更改):
$i = 0;
foreach ($array as $key => $value) {
$array[$key]['original_order'] = $i;
$i++;
}
uasort($array, function ($left, $right) {
if (isset($left['order'])) {
if(isset($right['order'])) {
if ($right['order'] == $left['order']) {
return $left['original_order'] < $right['original_order'] ? -1 : 1;
}
return $left['order'] < $right['order'] ? -1 : 1;
}
return -1;
} elseif(isset($right['order'])) {
return 1;
} else {
return $left['original_order'] < $right['original_order'] ? -1 : 1;
}
});
foreach ($array as $key => $value) {
unset($array[$key]['original_order']);
}