Сортировка массива по атрибуту времени в Rails - PullRequest
2 голосов
/ 02 апреля 2012

У меня есть массив объектов встреч, и я хотел бы отсортировать по атрибуту start_at.

my_array.uniq.sort_by! {|obj| obj.starts_at}

Однако я получил следующую ошибку: comparison of ActiveSupport::TimeWithZone with nil failed

Я уверен, что у меня нет nil-значения для start_at.В чем здесь проблема?Кроме того, как я могу сортировать по убыванию?

Обновление 1: Я понял, что Uniq!дает мне ноль, когда я вызываю .all метод для моего класса Appointment.Без uniq все работает нормально.

Appointment.all.uniq!

Обновление 2: Я не могу применить минус к obj.starts_at.Это дает мне ошибку: метод - не может быть найден в формате времени UTC.Вероятно, ч / б время не допускается равным нулю.Есть какие-нибудь мысли по поводу преодоления этого?

Обновление 3: my_array.uniq.sort { |x, y| (x.starts_at || nil) <=> (y.starts_at || nil)} работает в консоли, но когда я запускаю свое приложение, оно говорит: comparison of Event with Event failed

Последнееобновление: Следующие работы:

@events.sort_by!{|obj| (obj.starts_at.nil? ? 3.years.ago : obj.starts_at.utc)}

Мне нужно преобразовать формат даты в .utc и обработать пропущенный start_at (извините, я не знаю, почему у меня пропущен start_atатрибут объекта)

Ответы [ 5 ]

4 голосов
/ 02 апреля 2012

У меня есть ассоциация blog_post, у которой есть много blog_comments, и я сортирую массив blog_post согласно

to blog_comments count и он работает нормально ......

  @sort_blog = @blog_posts.sort_by { |i| i.blog_comments.count }

Я думаю, что у вас все хорошо, но проблема в том, что у вас есть нулевой объект, вы можете попробовать вот так

  my_array.uniq.sort_by! {|obj| obj.starts_at  unless obj.blank?}

Попробуй .........

2 голосов
/ 02 апреля 2012

Попробуйте это:

my_array.sort { |x, y| (x.starts_at || nil) <=> (y.starts_at || nil)}
2 голосов
/ 02 апреля 2012

У вас наверняка есть элемент с атрибутом nil start_at (но не обязательно с элементом nil в массиве).Однако ваша другая (боюсь, большая) проблема в том, что #sort_by!после того, как #uniq не изменяет ваш исходный массив, только временный, существующий между uniq и sort.

tmp = my_array.find_all { |e| e and e.starts_at }
my_array = tmp.uniq.sort_by { |obj| obj.starts_at }

Или, если хотите, вы можете написать его более читабельным для человека:

    ... find_all { |e| not e.nil? and not e.starts_at.nil? }

... но, прежде всего, выясните, каким образом start_at может быть нулем.

1 голос
/ 02 апреля 2012

Я бы сделал это так:

my_array.keep_if { |obj| obj.started_at }.uniq!.sort_by! {|obj| - obj.starts_at}

обратите внимание, что добавление - приведет к сортировке массива по убыванию

1 голос
/ 02 апреля 2012

Есть ли в вашем массиве объект nil?

Попробуйте это:

my_array.a.compact!
my_array.uniq.sort_by! {|obj| obj.starts_at}

Благодарим Майкла Коля за идиому (см. Комментарий).

Это эквивалентно:

my_array.reject!{|x| nil==x}   # my original answer 
my_array.reject!{|x| x.nil? }  # better idiom -- thanks Michael
my_array.compact!              # best idiom -- thanks Michael
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...