Как упорядочить некоторые значения в множественном массиве классов в Rails? - PullRequest
0 голосов
/ 14 января 2019

У меня есть массив, составленный из нескольких объектов класса, отсортированных по случайному порядку:

@streams = (Product.all + List.all + Post.all).shuffle

На странице канала (например, на странице шкалы времени в Facebook) содержимое объекта отображается с помощью .each, а для каждого класса применяется определенный фрагмент:

@streams.each do |stream|
  <% if stream.is_a?(Product) %>
   <%= render 'product_partial', object: stream %>
  <% elsif stream.is_a?(List) %>
   <%= render 'list_partial', object: stream %>
  <% end %>
 <% end %>

Цель: поскольку в приложении много продуктов (например, 200) и меньше сообщений (100) и еще меньше списков (10), я хочу отдать приказ каждому контенту с помощью класса. При этом сообщения и списки не будут утоплены в продуктах.

В одном предложении: для 20 товаров показать 2 поста, 1 список.

Есть идеи? Большое спасибо.

Ответы [ 2 ]

0 голосов
/ 14 января 2019

Я бы использовал вероятности и собственный перечислитель ruby:

@streams =
  [Product, List, Post].map(&:all).map(&:shuffle)

type =
  case rand 23
  when 0..19 then 0
  when 20..21 then 1
  else 2
  end

@streams[type].pop # pop one element from the respective array

У этого недостатка есть один тип, который может заканчиваться раньше других, и вам, вероятно, потребуется явно проверить это и использовать все еще не исчерпанные типы , но, похоже, это лучше, чем явный 1-per-per- 2 на 20, потому что он все еще имеет псевдослучайный порядок в некоторой степени.

0 голосов
/ 14 января 2019

Вы можете сделать что-то вроде:

@streams = custom_order(Products.all, Lists.all, Posts.all)

def custom_order(products, lists, posts)
  products_blocks = products.in_groups_of(20, false)
  lists_blocks = lists.in_groups_of(2, false)
  posts_blocks = posts.in_groups_of(1, false)

  result = []

  biggest_array = [products_blocks.length, lists_blocks.length, posts_blocks.length].max

  1.upto(biggest_array) do |_|
    # here we're pushing the blocks, result will be something like [[product, product .. product] [list, list] [posts]]
    result << products_blocks.shift
    result << lists_blocks.shift
    result << posts_blocks.shift
    # is ok if one of the blocks is nil, we'll use compact later
  end

  # result => [[product product product] [list list] [post] [product product] [list] nil]
  # compact to remove the nils
  # result => [[product product product] [list list] [post] [product product] [list]]
  # after flatten
  # result => [product product product list list post product product list]
  result.compact.flatten
end

РЕДАКТИРОВАТЬ: изменен компактный и выровнять

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...