【问题标题】:Sorting Laravel collection by 2 parameters按 2 个参数对 Laravel 集合进行排序
【发布时间】:2015-08-13 15:00:12
【问题描述】:

今天的排序很有趣!叹。我有一大堆雄辩的模型,这些模型需要通过一个参数在数组中组合在一起,并根据另一个参数在这些“团块”中排序。这可能很难解释:(

$master 是 Eloquent 结果的集合,我不知道如何在这里写出来,循环这个我可以访问所有模型函数/关系

$master = [];

这些有 2 个属性需要作为排序的基础,以下属性示例

//Object 1
$master->carry = 0;
$master->section = 'red';

//Object 2
$master->carry = 1;
$master->section = 'blue';

//Object 3
$master->carry = 0;
$master->section = 'blue';

我想对这些的大量集合进行排序,以便每个 $master-> 部分都位于数组中的一个“丛”中,并且在该“丛”中,$master->carry=0 产品列在最后。

From the example above I'd expect Object1, Object3, Object2

我尝试了一些不同的 $master->sort() 和 $master->sortBy() 东西,但是每个新的排序都会抛弃旧的排序:(

我目前有下面的代码,它将所有颜色分组,但它没有根据 $master->carry 排序它们

$order = array('red', 'blue', 'green');

    $master = $master->sort(function ($a, $b) use ($order) {
        $pos_a = array_search($a->sectionheader, $order);
        $pos_b = array_search($b->sectionheader, $order);
        return $pos_a - $pos_b;
    });

【问题讨论】:

    标签: php sorting laravel laravel-5 eloquent


    【解决方案1】:

    据我了解,您希望按以下方式对集合进行排序:

    • 按存储在 $order 数组中的顺序按部分排序
    • 在节内将带有 carry = 0 的元素移动到末尾

    您需要将实现此类逻辑的函数传递给 $master 集合。这个函数应该接受 2 个参数(集合的 2 个元素),比较它们并返回:

    • 0 如果元素相等
    • 1 如果第一个元素大于第二个元素
    • -1 如果第一个元素小于第二个元素

    在您的情况下,以下回调应该可以工作:

    $master = $master->sort(function ($a, $b) use ($order) {
      // get order of first element's section
      $pos_a = array_search($a->section, $order); 
      // get order of second element's section
      $pos_b = array_search($b->section, $order) 
      // if sections are different the value of carry doesn't matter 
      // as element's sections are enough to determine which of them is larger
      if ($pos_a != $pos_b) {
        return $pos_a - $pos_b;
      }
    
      // carry values are equal, so consider elements equal
      if ($a->carry == $b->carry) {
        return 0;
      }
    
      if (!$a->carry) {
        // if $a->carry is equal to 0 it should be put at the end, so after $b
        return 1;
      }
    
      if (!$b->carry) {
        // if $b->carry is equal to 0 it should be put at the end, so after $a
         return -1;
      }
    
      // otherwise elements can be considered equal
      return 0;
    });
    

    【讨论】:

    • 我认为这真的很接近,非常感谢伙计(这是你今天第二次提出一个惊人的例子,所以啤酒在我身上)。然而,这似乎完全抛弃了团块所在的原始顺序(id ASC),有没有办法只将携带物品排序到每个部分的底部而不交换每个“团块”的顺序 - 我刚刚意识到在携带物品之外是集合的结尾,其他一切都按正确的顺序排列。
    • 没关系,我添加了 $a->id 和 $b->id 的返回值,它运行良好。非常感谢您的时间和精力。谢谢老哥!!!
    • 就在第一个 if() 语句之后。干杯老兄
    猜你喜欢
    • 2021-01-15
    • 1970-01-01
    • 2021-03-08
    • 1970-01-01
    • 2021-04-21
    • 1970-01-01
    • 2015-10-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多