简体   繁体   English

Ruby方法以二进制形式返回哈希值

[英]Ruby method returns hash values in binary

I wrote a method that takes six names then generates an array of seven random numbers using four 6-sided dice. 我编写了一个方法,该方法使用六个名称,然后使用四个6边骰子生成七个随机数的数组。 The lowest value of the four 6-sided dice is dropped, then the remainder is summed to create the value. 丢弃四个6面骰子中的最低值,然后将其余的值相加以创建该值。 The value is then added to an array. 然后将该值添加到数组。

Once seven numbers have been generated, the array is then ordered from highest to lowest and the lowest value is dropped. 一旦生成了七个数字,则将数组从最高到最低排序,并删除最低值。 Then the array of names and the array of values are zipped together to create a hash. 然后将名称数组和值数组压缩在一起以创建哈希。

This method ensures that the first name in the array of names receives the highest value, and the last name receives the lowest. 此方法确保名称数组中的名字接收最高值,而名字接收最低值。

This is the result of calling the method: 这是调用该方法的结果:

{:strength=>1, :dexterity=>1, :constitution=>0, :intelligence=>0, :wisdom=>0, :charisma=>1}

As you can see, all the values I receive are either "1" or "0". 如您所见,我收到的所有值都是“ 1”或“ 0”。 I have no idea how this is happening. 我不知道这是怎么回事。

Here is the code: 这是代码:

module PriorityStatGenerator

  def self.roll_stats(first_stat, second_stat, third_stat, fourth_stat, fifth_stat, sixth_stat)
    stats_priority = [first_stat, second_stat, third_stat, fourth_stat, fifth_stat, sixth_stat].map(&:to_sym)
    roll_array = self.roll

    return Hash[stats_priority.zip(roll_array)]
  end

  private

  def self.roll

    roll_array = []

    7.times {
      roll_array << Array.new(4).map{ 1 + rand(6) }.sort.drop(1).sum
    }
    roll_array.reverse.delete_at(6)
  end
end

This is how I'm calling the method while I'm testing: 这是我在测试时调用方法的方式:

render plain: PriorityStatGenerator.roll_stats(params[:prioritize][:first_stat], params[:prioritize][:second_stat], params[:prioritize][:third_stat], params[:prioritize][:fourth_stat], params[:prioritize][:fifth_stat], params[:prioritize][:sixth_stat])

I added require 'priority_stat_generator' where I'm calling the method, so it is properly calling it. 我在调用该方法require 'priority_stat_generator'地方添加了require 'priority_stat_generator' ,因此它可以正确地调用它。

Can someone help me make it return proper values between 1 and 18? 有人可以帮助我让它返回介于1到18之间的正确值吗?

You need to learn to use IRB or PRY to test snippets of your code, or better, learn to use a debugger. 您需要学习使用IRB或PRY来测试代码片段,或者更好的是,学习使用调试器。 They give you insight into what your code is doing. 它们使您洞悉代码的作用。

In IRB: 在IRB中:

[7,6,5,4,3,2,1].delete_at(6)
1

In other words, delete_at(6) is doing what it's supposed to, but that's not what you want. 换句话说, delete_at(6)正在执行应有的操作,但这不是您想要的。 Instead, perhaps slicing the array will behave more like you expect: 相反,切片数组的行为可能更像您期望的那样:

>> [7,6,5,4,3,2,1][0..-2]
[
    [0] 7,
    [1] 6,
    [2] 5,
    [3] 4,
    [4] 3,
    [5] 2
]

Also, in your code, it's not necessary to return a value when that operation is the last logical step in a method. 另外,在您的代码中,当该操作是方法中的最后逻辑步骤时,不必return值。 Ruby will return the last value seen: Ruby将返回最后看到的值:

Hash[stats_priority.zip(roll_array)]

Here's a refactoring to simplify things and use an actually random number generator, as rand is notoriously terrible : 这是一种简化操作,并使用实际上是随机数生成器的重构,因为rand 非常糟糕

require 'securerandom'

module PriorityStatGenerator
  def self.roll_stats(*stats)
    Hash[
      stats.map(&:to_sym).zip(self.roll(stats.length).reverse)
    ]
  end

private
  def self.roll(n = 7)
    (n + 1).times.map do
      4.times.map { 1 + SecureRandom.random_number(6) }.sort.drop(1).inject(:+)
    end.sort.last(n)
  end
end

This makes use of inject(:+) so it works in plain Ruby, no ActiveSupport required. 这利用了inject(:+)因此可以在纯Ruby中工作,不需要ActiveSupport。

The use of *stats makes the roll_stats function way more flexible. *stats的使用使roll_stats函数的方式更加灵活。 Your version has a very rigid number of parameters, which is confusing and often obnoxious to use. 您的版本具有非常严格的参数数量,这令人困惑并且经常令人讨厌。 Treating the arguments as an array avoids a lot of the binding on the expectation that there's six of them. 将参数视为数组可避免由于有六个参数而产生的许多约束。

As a note it's not clear why you're making N+1 roles and then discarding the last. 需要说明的是,不清楚为什么要先创建N + 1个角色,然后放弃最后一个。 That's the same as generating N and discarding none. 这与生成N且不丢弃任何N相同。 Maybe you meant to sort them and take the N best? 也许您打算对它们进行排序并获得N最佳?

Update: Added sort and reverse to properly map in terms of priority. 更新:添加了sortreverse以正确地映射优先级。

As amadan said, I can't see how you are getting the results you are, but their is a definite bug in your code. 正如amadan所说,我看不到您是如何获得结果的,但是它们是代码中肯定的错误。

The last line in self.roll is the return value. self.roll的最后一行是返回值。

roll_array.reverse.delete_at(6)

Which is going to return the value that was deleted. 这将返回已删除的值。 You need to add a new lines to return the roll_array instead of the delete_at value. 您需要添加新行以返回roll_array而不是delete_at值。 You are also not sorting your array prior to removing that last item which will give you the wrong values as well. 您也不会在删除最后一个项目之前对数组进行排序,这也会给您错误的值。

def self.roll
  roll_array = []
  7.times {
    roll_array << Array.new(4).map{ 1 + rand(6) }.sort.drop(1).sum
  }
  roll_array.sort.drop(1) 
  roll_array
end

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM