【问题标题】:php complex laravel eloquent collection sortphp 复杂 laravel 雄辩的集合排序
【发布时间】:2016-02-24 21:21:55
【问题描述】:

我有相当复杂的 laravel eloquent 集合,需要按 projectid、日期、用户名排序。

我一直在搜索谷歌,但没有人询问或写过这种复杂的排序。

如果我只对 sortBy 函数使用 desc 或 asc 顺序。它可以工作,但如果我尝试同时使用 desc/asc 它会混淆..

我该如何解决这个问题???

集合结构

collection {
    array (size=148)
      0 => 
          attribute:
                id:100,
                date:"2015-02-03"
          relations: 
               0 project(belongstomany relationship)
                      projectid: 1
               1 user(belongstomany relationship)
                      username:"test"
}

这应该是这样排序的

project id(desc)   date(desc)  name(asc)
9                  2015-02-31  test1
9                  2015-02-30  test2
8                  2015-02-30  test2
7                  2015-02-29  test3
6                  2015-02-28  test4
5                  2015-02-27  test5

【问题讨论】:

  • 你想在这里做什么?您是在尝试创建新集合还是对现有集合进行排序?
  • 基本上,我检索了数据并通过关系进行了雄辩的收集。我正在整理现有的。
  • 然后,如果您根据多个标准对它们进行排序,结果将混合在一起。因为你不能保证最大 id 也有最大日期,也有最大名称
  • 那么这个问题没有解决办法??
  • 愚蠢的解决方案:打破集合并将属性放入三个不同的数组中。对它们进行排序。创建一个新集合。

标签: php sorting laravel laravel-collection


【解决方案1】:

你可以做你想做的事,但你必须使用sort() 方法,而不是sortBy() 方法。 sort() 方法将采用一个闭包,您可以使用它来定义您的自定义排序算法。基本上,如果你将闭包传递给sort(),它会调用PHP 的usort() 和你的闭包来对项目进行排序。

这只是您要查找的内容的粗略概念。您可能必须对其进行调整,因为您发布的内容几乎没有不确定性。您可以将其定义为传递给sort() 的实际函数,也可以将其作为匿名函数传递给sort()

function ($a, $b) {
    /**
     * Your question states that project is a belongsToMany relationship.
     * This means that project is a Collection that may contain many project
     * objects, and you need to figure out how you want to handle that. In
     * this case, I just take the max projectid from the Collection (max,
     * since this field will be sorted desc).
     * 
     * If this is really just a belongsTo, you can simplify this down to
     * just $a->project->projectid, etc.
     */
    $aFirst = $a->project->max('projectid');
    $bFirst = $b->project->max('projectid');

    /**
     * If the projectids are equal, we have to dig down to our next comparison.
     */    
    if ($aFirst == $bFirst) {
        /**
         * Since the first sort field (projectids) is equal, we have to check
         * the second sort field.
         */

        /**
         * If the dates are equal, we have to dig down to our next comparison.
         */
        if ($a->date == $b->date) {
            /**
             * Your question states that user is a belongsToMany relationship.
             * This means that user is a Collection that may contain many user
             * objects, and you need to figure out how you want to handle that.
             * In this case, I just take the min username from the Collection
             * (min, since this field will be sorted asc).
             */
            $aThird = $a->user->min('username');
            $bThird = $b->user->min('username');

            /**
             * If the final sort criteria is equal, return 0 to tell usort
             * that these two array items are equal (for sorting purposes).
             */
            if ($aThird == $bThird) {
                return 0;
            }

            /**
             * To sort in ascending order, return -1 when the first item
             * is less than the second item.
             */
            return ($aThird < $bThird) ? -1 : 1;
        }

        /**
         * To sort in descending order, return +1 when the first item is
         * less than the second item.
         */
        return ($a->date < $b->date) ? 1 : -1;
    }

    /**
     * To sort in descending order, return +1 when the first item is
     * less than the second item.
     */
    return ($aFirst < $bFirst) ? 1 : -1;
}

有关usort() 工作原理的更多信息,您可以check the docs

【讨论】:

    猜你喜欢
    • 2020-03-19
    • 2015-03-04
    • 1970-01-01
    • 2018-12-12
    • 2015-08-15
    • 1970-01-01
    • 2018-04-05
    • 2014-01-16
    • 2018-11-07
    相关资源
    最近更新 更多