如何根据参数对数组进行排序

时间:2014-02-21 18:08:13

标签: php arrays

我有这样的JSON:

{
    "class": {
        "type": "major",
        "order": "1"
    },
    "number": {
       "type": "date",
       "order": "5"
    },
    "amount": {
        "type": "date",
        "order": "3"
    },
}

我需要将其转换为PHP数组并基于order字段进行排序。

如果数字相同,则订单应保持不变。

编辑:

此外,如果某些元素没有order,那么它们应该位于底部

2 个答案:

答案 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']);
}