开发者

Split @blogs into three divs using size of description field as weight

开发者 https://www.devze.com 2023-01-19 07:37 出处:网络
I have a collection of Blog items. @blogs = Blog.find(:all) Each blog has a description textfield with some text. What I would like to do is splitting the @blogs objects into 3 divs, but with rough

I have a collection of Blog items.

@blogs = Blog.find(:all)

Each blog has a description textfield with some text. What I would like to do is splitting the @blogs objects into 3 divs, but with roughly the same characters in each column.

<div id="left">
  #blog1 (653 characters)
</div>

<div id="center">
  #blog2 (200 characters)
  #blog5 (451 characters)
</div>

<div id="right">
  #blog3 (157 characters)
  #blog4 (358 characters)
  #blog6 (155 characters)
</div>

I can't figure out how to do that without getting really complicated and probably inefficient.

So far I have thought about converting the description field (size) to % of total characters in the @blogs collection, but how do I match/split the elements, so that I get closest to 33% in each 开发者_JAVA百科column - like a super simple tetris game :)

Any thoughts?


Here's a quick hack that isn't perfect, but might get you pretty close. The algorithm is simple:

  1. Sort items by size.
  2. Partition items into N bins.
  3. Resort each bin by date (or other field, per your desired presentation order)

Here's a quick proof of concept:

#!/usr/bin/env ruby

# mock out some simple Blog class for this example
class Blog
  attr_accessor :size, :date

  def initialize
    @size = rand(700) + 100
    @date = Time.now + rand(1000)
  end
end

# create some mocked data for this example
@blogs = Array.new(10) { Blog.new }

# sort by size
sorted = @blogs.sort_by { |b| b.size }

# bin into NumBins
NumBins = 3
bins = Array.new(NumBins) { Array.new }
@blogs.each_slice(NumBins) do |b|
  b.each_with_index { |x,i| bins[i] << x }
end

# sort each bin by date
bins.each do |bloglist|
  bloglist.sort_by! { |b| b.date }
end

# output
bins.each_with_index do |bloglist,column|
  puts
  puts "Column Number: #{column+1}"
  bloglist.each do |b|
    puts "Blog: Size = #{b.size}, Date = #{b.date}"
  end
  total = bloglist.inject(0) { |sum,b| sum + b.size }
  puts "TOTAL SIZE: #{total}"
end

For more ideas, look up the multiprocessor scheduling problem.

0

精彩评论

暂无评论...
验证码 换一张
取 消