PHP 中对象数组的复杂排序

发布于 2024-10-23 20:07:32 字数 2029 浏览 2 评论 0原文

我需要通过多次比较对论坛程序的对象数组进行排序。每个帖子(主线程或回复)都是 Post 类的一个实例。我需要按 timeLastChanged 属性对主线程进行排序(用于碰撞),然后按 timeStarted 属性对它们下面的回复进行排序(最旧的在前)。我的目标是按照论坛表中显示的确切顺序对数组进行排序。简单地,排序和显示如下:

- Main thread
   - Reply
      - Reply
   - Reply
   - Reply
      - Reply
         - Reply
- Main thread

等等
我看过 usort 等,但我无法弄清楚比较函数如何实现这一点。哦,每个对象都有一个属性 isReply,如果它不是回复,则设置为 0;如果是回复,则设置为它所回复的帖子的线程 ID。每个对象都有一个属性TID,它是它的线程ID(唯一的)。我还有一个名为 numReplies 的属性,它显示一条消息有多少个直接回复(当然,回复将有自己的 numReplies 来显示分配给该回复的回复数量等)。

我已经将显示部分放下并从数据库中获取信息,我只是不确定对其进行排序的最有效方法。感谢您的任何帮助。

编辑:这是我启动类的代码,我排除了从数据库中获取数据的部分,但只知道 Post 的所有适用实例都分配给它们各自的对象数组(回复在replyObjs中,主电源位于 mainsObjs 等中):

class Category {

    public $title;
    public $majCatID;
    public $catID;
    public $modLevel;
    public $postingLevel;
    public $hostedByUID;
    public $order;
    public $shortName;
    public $info;
    public $stickyObjs;
    public $mainsObjs;
    public $replyObjs;
    public $orderedObjs;
    private $database;

    public function __construct($catID) {
        $this->database = new TBDatabase;
        $result = $this->database->getIntRow(CAT_TABLE, 'catID', $catID);
        $row = $this->database->fetchAssoc($result);
        $this->title = $row['title'];
        $this->majCatID = $row['majCatID'];
        $this->catID = $row['catID'];
        $this->modLevel = $row['modLevel'];
        $this->postingLevel = $row['postingLevel'];
        $this->hostedByUID = $row['hostedByUID'];
        $this->order = $row['order'];
        $this->shortName = $row['shortName'];
        $this->info = $row['info'];
        }
    public function sortPosts() {
        $table = $this->shortName."_threads";
        $this->getStickyObjs();
        $numStickies = count($this->stickyObjs);
        $this->getMainObjs();
        $numMains = count($this->mainsObjs);
        $this->getReplyObjs();
        $numReplies = count($this->replyObjs);
        }

I need to sort an array of objects for a forum program with multiple comparisons. Each post (main thread or reply) is an instance of a class Post. I need to sort the main threads by their timeLastChanged property (for bumping) and then sort the replies underneath them by their timeStarted property (oldest first). My goal was to sort the array in the exact order it would be displayed in the forum table. Simply, sorted and displayed like this:

- Main thread
   - Reply
      - Reply
   - Reply
   - Reply
      - Reply
         - Reply
- Main thread

etc.
I've looked at usort and the like but I can't figure how the comparison functions would work to do this. Oh, and each object has a property isReply that is set to 0 if it isn't a reply and set to the thread ID of the post it is a reply of, if it is a reply. Each object has a property TID which is its thread ID (unique). I also have a property called numReplies that shows how many direct replies a message has (and then, of course, replies would have their own numReplies that show how many replies are assigned to that reply, etc).

I've got the displaying part down and the grabbing the info from the database, I'm just not sure of the most efficient way of sorting it. Thanks for any help.

Edit: here is the code I have that starts the class, I excluded the part where I grab the data from the database, but just know that all the applicable instances of Post are assigned to their respective array of objects (replies are in replyObjs, mains are in mainsObjs, etc):

class Category {

    public $title;
    public $majCatID;
    public $catID;
    public $modLevel;
    public $postingLevel;
    public $hostedByUID;
    public $order;
    public $shortName;
    public $info;
    public $stickyObjs;
    public $mainsObjs;
    public $replyObjs;
    public $orderedObjs;
    private $database;

    public function __construct($catID) {
        $this->database = new TBDatabase;
        $result = $this->database->getIntRow(CAT_TABLE, 'catID', $catID);
        $row = $this->database->fetchAssoc($result);
        $this->title = $row['title'];
        $this->majCatID = $row['majCatID'];
        $this->catID = $row['catID'];
        $this->modLevel = $row['modLevel'];
        $this->postingLevel = $row['postingLevel'];
        $this->hostedByUID = $row['hostedByUID'];
        $this->order = $row['order'];
        $this->shortName = $row['shortName'];
        $this->info = $row['info'];
        }
    public function sortPosts() {
        $table = $this->shortName."_threads";
        $this->getStickyObjs();
        $numStickies = count($this->stickyObjs);
        $this->getMainObjs();
        $numMains = count($this->mainsObjs);
        $this->getReplyObjs();
        $numReplies = count($this->replyObjs);
        }

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

神仙妹妹 2024-10-30 20:07:33

您正在对对象数组进行排序,因此 PHP 数组函数 并没有真正运行除非您想按数组键排序,否则可以帮助您。

您必须循环访问对象数组并访问对象属性并按照您想要的顺序重建数组。如果没有看到您的一些代码,就不可能提供更多细节。

当您从数据库中提取数据时,最好在那里进行排序。

如果您有一个类“Article”,那么它可以有一个方法“getComments”,该方法可以直接执行数据库调用或涉及一些其他类/方法来检索该文章的评论。不过,在数据库中排序可能是最好的选择,因为您也可以在检索它们时对它们进行排序。这就是数据库的作用。

这是一个空气代码示例。这是一个递归函数。所以要小心。

public function getComments($id, $sort)
{
    $sorted = array();
    $comments = $this->getChildren($id, $sort); // make getChildren return null if no children records.
    if (!is_null($comments) && count($comments) > 0)
    {
        foreach ($comments as $comment)
        {
            $sorted[$comment['id']] = $comment;
            $sorted[$comment['id']]['children'] = $this->getComments($comment['id'], $sort);
        }
    }
    else
    {
        $sorted = $comments;
    }
    return $sorted;
}

You are sorting an array of objects, so the PHP array functions are not really going to help you unless you want to sort by the array keys.

You'll have to loop over the array of objects and access the objects properties and rebuild your array in the order you want. Without seeing some of your code, it's not really possible to give more detail.

As you are pulling the data from the database, it's probably best to do the sorting there.

If you have a class "Article" then it can have a method "getComments" which may do the database calls directly or involve some other classes/methods to retrieve the comments for that article. Though, sorting in the database is probably the best all round, as you may as well sort them while retrieving them. That's what databases do.

Here is an air code example. It's a recursive function. So be careful.

public function getComments($id, $sort)
{
    $sorted = array();
    $comments = $this->getChildren($id, $sort); // make getChildren return null if no children records.
    if (!is_null($comments) && count($comments) > 0)
    {
        foreach ($comments as $comment)
        {
            $sorted[$comment['id']] = $comment;
            $sorted[$comment['id']]['children'] = $this->getComments($comment['id'], $sort);
        }
    }
    else
    {
        $sorted = $comments;
    }
    return $sorted;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文