0

I am trying to do a multiple sortBy on a collection and seems like is not working properly:

$myCollection = collect([
    ['foo' => 3, 'bar' => null, 'active' => 1],
    ['foo' => 2, 'bar' => null, 'active' => 1],
    ['foo' => 1, 'bar' => 1, 'active' => 1],
])->sortBy('foo')->sortBy('bar')->sortBy('active');

Result:

Illuminate\Support\Collection {#417 ▼
  #items: array:3 [▼
    0 => array:3 [▼
      "foo" => 3
      "bar" => null
      "active" => 1
    ]
    1 => array:3 [▼
      "foo" => 2
      "bar" => null
      "active" => 1
    ]
    2 => array:3 [▼
      "foo" => 1
      "bar" => 1
      "active" => 1
    ]
  ]
}

First sorts properly by active (they are all the same = 1)

Then sorts properly by "bar" (null < 1)

Then sortBy('foo') fails, because (2<3), but shows 3 first before 2... Expecting result:

Illuminate\Support\Collection {#417 ▼
  #items: array:3 [▼
    0 => array:3 [▼
      "foo" => 2
      "bar" => null
      "active" => 1
    ]
    1 => array:3 [▼
      "foo" => 3
      "bar" => null
      "active" => 1
    ]
    2 => array:3 [▼
      "foo" => 1
      "bar" => 1
      "active" => 1
    ]
  ]
}

This is a sample I did for the presentation. In my real scenario I am using Collection::macro with custom function callbacks to compare dates... but even in this simple example things are looks like not working.

1 Answer 1

1

You are chaining three different sortings, and in this case you can be sure only that last applied sort has been properly done.

So try to pass array of sort operations:

$myCollection = collect(...)->sortBy([
    ['foo', 'asc'],
    ['bar', 'asc'],
    ['active', 'asc'],
]);

More info you can find in the documentation.

Sign up to request clarification or add additional context in comments.

1 Comment

Yes, thanks. I just saw it. Thank you. $myCollection = collect([ ['foo' => 3, 'bar' => null, 'active' => 1], ['foo' => 2, 'bar' => null, 'active' => 1], ['foo' => 1, 'bar' => 1, 'active' => 1], ]); $sorted = $myCollection->sortBy([ fn ($a, $b) => $a['active'] <=> $b['active'], fn ($a, $b) => $a['bar'] <=> $b['bar'], fn ($a, $b) => $a['foo'] <=> $b['foo'], ]);

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.