# Sort by time?

**URL:** <https://forum.crystal-lang.org/t/sort-by-time/6918>\
**Category:** Help & Support\
**Created:** [June 11, 2024, 3:26am UTC](https://forum.crystal-lang.org/t/sort-by-time/6918 "2024-06-11T03:26:53Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![rob](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/rob/32/1409_2.png) [@rob](https://forum.crystal-lang.org/u/rob)\
**Post date:** [June 11, 2024, 3:26am UTC](https://forum.crystal-lang.org/t/sort-by-time/6918/1 "2024-06-11T03:26:53Z")

</div>

Tonight I tried to run this code:

```crystal
    broadcast.transcriptions
      .sort! { |transcription| transcription.created_at.to_unix }
      .last

```

broadcast and transcription are Avram model instances, and created\_at is a Time.

I was at first surprised that crystal’s Array#sort doesn’t know how to compare Time, but I jumped to #to\_unix thinking that’d be an easy escape. Unfortunately, this cryptic reaper (still) popped out of the compiler:

```auto
Error target worker failed to compile:
In /Users/robert/.asdf/installs/crystal/1.11.2/src/array.cr:1661:10

1661 | {% raise "Expected block to return Int32 or Nil, not #{U}" %}
          ^----
Error: Expected block to return Int32 or Nil, not Int64

```

Brutal! Both a dead end, and a cryptic error message ☠

Is there a way to trick the sorting algorithm to sort by something like Time, which is quite sortable if you know what you’re doing?

---

<div class="post-metadata">

**Author:** ![Blacksmoke16](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/blacksmoke16/32/1241_2.png) [@Blacksmoke16](https://forum.crystal-lang.org/u/Blacksmoke16)\
**Post date:** [June 11, 2024, 3:42am UTC](https://forum.crystal-lang.org/t/sort-by-time/6918/2 "2024-06-11T03:42:56Z")

</div>

You probably want to use `#sort_by!`, otherwise the block version of `#sort!` expects you to return `0`, `1`, `-1`, or `nil` as per semantics of `<=>`. There’s also no reason to call `#to_unix` as `Time` values include `Comparable` inherently.

Also might be more efficient to just do the sort directly in the SQL with a `LIMIT 1` if that would be possible. ~~Otherwise you could prob get away with just calling `#max` or `#min` vs having to sort at all.~~ This would have to be `#max_by` like @straight-shoota pointed out since it’s not a collection of `Time` directly.

---

<div class="post-metadata">

**Author:** ![beta-ziliani](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/beta-ziliani/32/1821_2.png) [@beta-ziliani](https://forum.crystal-lang.org/u/beta-ziliani)\
**Post date:** [June 11, 2024, 3:30pm UTC](https://forum.crystal-lang.org/t/sort-by-time/6918/3 "2024-06-11T15:30:47Z")

</div>

I created a little PR to improve the error: [Better error reporting for `sort` by beta-ziliani · Pull Request #14693 · crystal-lang/crystal · GitHub](https://github.com/crystal-lang/crystal/pull/14693)

---

<div class="post-metadata">

**Author:** ![rob](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/rob/32/1409_2.png) [@rob](https://forum.crystal-lang.org/u/rob)\
**Post date:** [June 11, 2024, 4:15pm UTC](https://forum.crystal-lang.org/t/sort-by-time/6918/4 "2024-06-11T16:15:25Z")

</div>

#sort\_by is indeed what I needed, thank you!

---

<div class="post-metadata">

**Author:** ![straight-shoota](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/straight-shoota/32/36_2.png) [@straight-shoota](https://forum.crystal-lang.org/u/straight-shoota)\
**Post date:** [June 11, 2024, 4:26pm UTC](https://forum.crystal-lang.org/t/sort-by-time/6918/5 "2024-06-11T16:26:11Z")

</div>

If you want the last (i.e. maximum) value, wouldn’t `transcriptions.max_by(&.created_at)` be sufficient?
