【问题标题】:PHP - sort arrays of arrays which are values of an assoc array, by element of lowest level arrayPHP - 按最低级别数组的元素对作为 assoc 数组值的数组数组进行排序
【发布时间】:2014-06-04 08:31:22
【问题描述】:

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

对不起标题,开始扩展我的描述能力! 我有一个 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)

【问题讨论】:

  • 那么最终的输出是什么? banana = [1,1], [2,1], [3, 1], orange = [1, 1], [3,1], [5,1] ?
  • 是的!就是这样,我会做一个编辑

标签: php arrays sorting


【解决方案1】:

您的比较功能出现故障。您需要对“else”进行分组,或者它执行以下操作(我相信):在第一个 else 情况下,它评估 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]; });
}

【讨论】:

  • 啊,就是这样,你是明星。我实际上曾经尝试过第二个比较函数,但那是在我意识到我需要在 foreach 中引用之前。双重打击......
【解决方案2】:

或者,您可以结合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
                )

        )

)

【讨论】:

  • 谢谢你 - 我想我更喜欢另一种方式,但我会把这个放在口袋里以备不时之需!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多