尝试在 php 中使用 usort 对对象数组进行排序

Trying to sort an array of objects using usort in php

我正在 WordPress 网站上工作,试图对 post 标签进行排序,这是一个包含各种成员的对象数组,包括 slugname。我已经按优先顺序创建了一个标签 slug 字符串数组,并尝试根据该数组的值对 post 的标签数组进行排序,并以 post 的 slug 作为键。示例:

$tagPriorityMap = array(
  "research" => 0,
  "strategy" => 1,
  "naming" => 2,
  "identity" => 3,
  "packaging" => 4,
  "environment" => 5,
  "digital" => 6,
);
function sort_tags($a, $b) {
  if ($tagPriorityMap[$a->slug] == $tagPriorityMap[$b->slug]) {
    return 0;
  }
  return ($tagPriorityMap[$a->slug] < $tagPriorityMap[$b->slug]) ? -1 : 1;
}

如果我在 sort_tags 函数中回显一些代码,它表明 $a->slug 是一个类似于“strategy”的字符串,但它也表明 $tagPriorityMap[$a->slug] returns没有价值。我究竟做错了什么?谢谢。

你的$tagPriorityMap必须在函数内部声明为全局变量。 试试看:

function sort_tags($a, $b) {
  global $tagPriorityMap;
  if ($tagPriorityMap[$a->slug] == $tagPriorityMap[$b->slug]) {
    return 0;
  }
  return ($tagPriorityMap[$a->slug] < $tagPriorityMap[$b->slug]) ? -1 : 1;
}

已添加 创意来自 Maik Lowrey

只需添加 $tagPriorityMap 作为全局使用的函数参数

function sort_tags($a, $b, $tagPriorityMap) {
  if ($tagPriorityMap[$a->slug] == $tagPriorityMap[$b->slug]) {
    return 0;
  }
  return ($tagPriorityMap[$a->slug] < $tagPriorityMap[$b->slug]) ? -1 : 1;
}

我真的很奇怪为什么@Cârnăciov 删除了他的答案,它比被接受的答案要好得多。
将优先级转储到全局中对于测试来说是可以的,但是如果您通过乱用全局名称空间来解决所有问题,您很快就会遇到麻烦。

您可以像 Cârnaciov 建议的那样使用 use() 关键字来避免这种情况。

但是您可以直接在函数内将优先级定义为静态变量。它的行为与全局完全一样,除了比较函数之外没有人会看到它。
PHP7 spaceship operator 也可以用来简化比较,它是为此量身定做的:

function sort_tags ($a, $b) {
        static $prio = array(
          "research" => 0,
          "strategy" => 1,
          "naming" => 2,
          "identity" => 3,
          "packaging" => 4,
          "environment" => 5,
          "digital" => 6,
        );
        return $prio[$a->slug] <=> $prio[$b->slug];
    }

或者您也可以使用 arrow functions。这些允许您模拟过去 25 年 JavaScript 处理闭包的复杂方式 :D
(不好意思,开个玩笑)

$sort_tags = (function () { // this anonymous function closes over "prio"
        $prio = array(      // and returns the actual comparison function
          "research" => 0,
          "strategy" => 1,
          "naming" => 2,
          "identity" => 3,
          "packaging" => 4,
          "environment" => 5,
          "digital" => 6,
        );
        // the comparison function sees "prio" captured in the upper level closure
        return fn ($a, $b) => 
            $prio[$a->slug] <=> $prio[$b->slug]; // handles the -1, 0 and 1 cases in one go
    })(); // immediately invoked function expression, just like in JavaScript

证明您不再需要全局的愚蠢示例:

文件test.php

<?php

function demo () {
    
    $sort_tags = function ($a, $b) {
            static $prio = array(
              "research" => 0,
              "strategy" => 1,
              "naming" => 2,
              "identity" => 3,
              "packaging" => 4,
              "environment" => 5,
              "digital" => 6,
            );
            return $prio[$a->slug] <=> $prio[$b->slug];
    };


    $sample = [
        (object)["slug" => "naming"   , "id" => 1],
        (object)["slug" => "packaging", "id" => 2],
        (object)["slug" => "research" , "id" => 3],
        (object)["slug" => "strategy" , "id" => 4]];

    echo "<br>before usort:<br><br>";
    foreach ($sample as $item) echo $item->slug, " => ", $item->id, "<br>";
    echo "<br>after usort:<br><br>";

    usort ($sample, $sort_tags);

    foreach ($sample as $item) echo $item->slug, " => ", $item->id, "<br>";
}

demo();
?>

浏览器输出

before usort:

naming => 1
packaging => 2
research => 3
strategy => 4

after usort:

research => 3
strategy => 4
naming => 1
packaging => 2