PHP - 按最低级别数组的元素排序数组的数组,这些数组是assoc数组的值

时间:2014-06-04 00:10:28

标签: php arrays sorting

这是this slightly simpler question的后续行动。主要区别是被排序项目的复杂性增加(数组,而不是整数),需要使用

对标题感到抱歉,开始扩展我的描述能力! 我有一个PHP关联数组,字符串作为键。每个值都是一个2元素数组的数组(它们是图形的数据点)。我想根据点中第一个元素的数值对每个点数组进行排序。我确信这应该很简单,而且我已经找到了足够多的例子,我认为我应该做正确的事情,但它不是很有效,所以有一个错字或者我是个白痴或什么......

PHP:

//Each fruit corresponds to an array (series) of 2-element arrays (data points)
$data = [
    'banana' => [
        [1,1],[3,1],[2,1]
    ],
    'orange' => [
        [5,1],[1,1],[3,1]
    ]
];

echo "Before sort:\n";
var_dump($data);

//For each fruit, I want to order the 2-element arrays by the first element
//NB following previous Q tried & to force reference, doesn't seem to work here
foreach ($data as $key => &$series)
{
    usort($series, 'sortByZeroethElement');
}

echo "\n\nAfter sort:\n";
var_dump($data);

function sortByZeroethElement($a, $b)
{
    return (int) $a[0] > (int) $b[0] ? 1 : (int) $a[0] == (int) $b[0] ? 0 : -1;
}

输出:

Before sort:
array(2) {
  'banana' =>
  array(3) {
    [0] =>
    array(2) {
      [0] =>
      int(1)
      [1] =>
      int(1)
    }
    [1] =>
    array(2) {
      [0] =>
      int(3)
      [1] =>
      int(1)
    }
    [2] =>
    array(2) {
      [0] =>
      int(2)
      [1] =>
      int(1)
    }
  }
  'orange' =>
  array(3) {
    [0] =>
    array(2) {
      [0] =>
      int(5)
      [1] =>
      int(1)
    }
    [1] =>
    array(2) {
      [0] =>
      int(1)
      [1] =>
      int(1)
    }
    [2] =>
    array(2) {
      [0] =>
      int(3)
      [1] =>
      int(1)
    }
  }
}


After sort:
array(2) {
  'banana' =>
  array(3) {
    [0] =>
    array(2) {
      [0] =>
      int(2)
      [1] =>
      int(1)
    }
    [1] =>
    array(2) {
      [0] =>
      int(3)
      [1] =>
      int(1)
    }
    [2] =>
    array(2) {
      [0] =>
      int(1)
      [1] =>
      int(1)
    }
  }
  'orange' =>
  array(3) {
    [0] =>
    array(2) {
      [0] =>
      int(3)
      [1] =>
      int(1)
    }
    [1] =>
    array(2) {
      [0] =>
      int(1)
      [1] =>
      int(1)
    }
    [2] =>
    array(2) {
      [0] =>
      int(5)
      [1] =>
      int(1)
    }
  }
}

期望的结果:

'banana' => [
        [1,1],[2,1],[3,1]
    ],
    'orange' => [
        [1,1],[3,1],[5,1]
    ]

正如您所看到的,在输出中,内部点数组尚未排序。我究竟做错了什么? (PHP 5.5.9,Windows 7)

2 个答案:

答案 0 :(得分:3)

您的比较功能出现故障。您需要对“其他”进行分组,或者执行以下操作(我相信):在第一种情况下,它会对1(int) $a[0] == (int) $b[0]进行评估。然后,下一个?会再次将其评估为布尔值(1 == true(int) $a[0] == (int) $b[0])。我添加了2个括号,这对我有用:

function sortByZeroethElement($a, $b)
{
    return (int) $a[0] > (int) $b[0] ? 1 : ((int) $a[0] == (int) $b[0] ? 0 : -1);
}

还有一个使用lambda和一些数学的较短版本:

foreach ($data as $key => &$series)
{
    usort($series, function($a, $b) { return $a[0] - $b[0]; });
}

答案 1 :(得分:1)

或者,您可以与serialize/unserialize一起执行简单的foreach循环。考虑这个例子:

$data = [
    'banana' => [
        [1,1],[3,1],[2,1]
    ],
    'orange' => [
        [5,1],[1,1],[3,1]
    ]
];

foreach($data as $fruit => $values) {
    $temp = array();
    foreach($values as &$value) {
        $temp[] = serialize($value);
    }
    sort($temp);
    $temp = array_map('unserialize', $temp);
    $data[$fruit] = $temp;
}

echo '<pre>';
print_r($data);
echo '</pre>';

示例输出:

Array
(
    [banana] => Array
        (
            [0] => Array
                (
                    [0] => 1
                    [1] => 1
                )

            [1] => Array
                (
                    [0] => 2
                    [1] => 1
                )

            [2] => Array
                (
                    [0] => 3
                    [1] => 1
                )

        )

    [orange] => Array
        (
            [0] => Array
                (
                    [0] => 1
                    [1] => 1
                )

            [1] => Array
                (
                    [0] => 3
                    [1] => 1
                )

            [2] => Array
                (
                    [0] => 5
                    [1] => 1
                )

        )

)