按属性排序并随机化重复

时间:2016-07-08 09:06:45

标签: ruby ruby-on-rails-4 rspec

鉴于Venue有一个字段" featured_level"可以从0到N。

我需要返回由featured_level排序的场地,,但是使用相同的featured_level随机化场地的顺序

更新:

使用给定的答案我有这个方法:

def self.by_featured_level
  all.group_by {|v| v.featured_level}.inject([]) { |memo, (level,values)|
    memo << { level => values.shuffle }
  }.map { |hash| hash.values }.flatten.reverse
end

但它没有通过以下测试(也没有与实数一起正常工作),我还在试图解决它,测试使用:

describe "by featured level" do
  before do

    @venue1 = create(:venue, featured_level: 5)
    @venue2 = create(:venue, featured_level: 2)
    @venue3 = create(:venue, featured_level: 4)
    @venue4 = create(:venue, featured_level: 2)
    @venue5 = create(:venue, featured_level: 0)
    @venue6 = create(:venue, featured_level: 2)
    @venues = Venue.by_featured_level

  end

  it { 
    start_with_hightest = @venues.index(@venue1) == 0
    expect(start_with_hightest).to be_truthy
  }
  it {
    second_hightest_is_2nd = @venues.index(@venue3) == 1
    expect(second_hightest_is_2nd).to be_truthy
  }
  it {
    ends_with_lowest = @venues.last.id == @venue5.id
    expect(ends_with_lowest).to be_truthy
  }
end

2 个答案:

答案 0 :(得分:1)

让我们从收集场地开始:

require 'ostruct'

@venue1 = OpenStruct.new(id: :a, level: 0)
@venue2 = OpenStruct.new(id: :b, level: 2)
@venue3 = OpenStruct.new(id: :c, level: 2)
@venue4 = OpenStruct.new(id: :d, level: 2)
@venue5 = OpenStruct.new(id: :e, level: 4)
@venue6 = OpenStruct.new(id: :f, level: 5)

@venues = [@venue1, @venue2, @venue3, @venue4, @venue5, @venue6]

我们希望每个级别随机化,因此我们将创建组:

@venues.group_by { |v| v.level }

这将返回一个哈希,其中场地被每个级别编入索引。

现在迭代哈希并返回值已随机化的新哈希:

@venues.
  group_by {|v| v.level}.
  inject([]) { |memo, (level,values)|
   memo << { level => values.shuffle }
  }

此哈希现在可以展平,因此最终结果是哈希列表,每个级别随机化:

@venues.
  group_by {|v| v.level}.
  inject([]) { |memo, (level,values)|
   memo << { level => values.shuffle }
  }.
  map { |hash| hash.values }.
  flatten

答案 1 :(得分:0)

我最初需要一个ActiveRecord :: Relation而不是一个数组(由@ zezetic的答案返回,所以最后我做了:

Error in combn(r2, 2, function(x) subset(x, sum(x) == 2300)) : 
  dims [product 1125750] do not match the length of object [0]