Ruby:将int和store转换为数组

时间:2016-11-02 18:38:25

标签: arrays ruby

在我的第一个ruby hw任务中,我必须制作一个FizzBu​​zz程序。 (如果int为/ 3,则将其转换为" Fizz"字符串,如果可被5整除,则为" Buzz"字符串,如果是" FizzBu​​zz"字符串。)最后,如果不能被任何一个整除,我需要将数字本身转换为字符串并将其存储在名为main的方法中的数组中。

class FizzBuzz
  def initialize(int_num, str_fb, value)
   self.int_num = int_num
   self.str_fb = str_fb
   self.value = value
  end

  def int_num
   @int_num
  end

  def int_num=(num)
   raise TypeError if not num.is_a? Integer
   @num = int_num
  end

   def str_fb
    @str_fb
   end

  def str_fb=(name)
    if int_num % 3 == 0
      int_num = "Fizz"
    elsif int_num % 5 == 0
       int_num = "Buzz"
    elsif int_num % 5 == 0 and int_num % 3 == 0
       int_num = "FizzBuzz"
    else
      str_fb = int_num.to_s     #Also needs to be stored in an array in main function
  end


  def main
    ary =array.new
  end
end

如何将新转换的int_num(现在是一个字符串)存储到main中的数组中?此外,上面的代码只是该类的一种方法,但它看起来是否正确?谢谢,我是一个完整的Ruby noob,并感谢所有的帮助。

**添加完整代码。仍然不完整,因为我需要创建一个getter和setter for value for loops 1-50。

2 个答案:

答案 0 :(得分:0)

您可以使用push方法或<<(铲除)运算符将数据添加到数组中。我更喜欢后者。

以下是我对你的任务的看法:

module MyModule
  class FizzBuzz
    attr_reader :main

    def initialize(range)
      raise TypeError unless range.is_a? Range
      @main = []
      range.to_a.each do |i|
        main << process(i)
      end
    end

    private

    def process(num)
      if num % 5 == 0 && num % 3 == 0
        "FizzBuzz"
      elsif num % 3 == 0
        "Fizz"
      elsif num % 5 == 0
        "Buzz"
      else
        num
      end
    end
  end
end

请注意,我没有任何getter和setter方法。这有两个原因:

  1. 通过调用attr_reader类方法,我以更优雅的方式为main设置公共getter方法
  2. 我认为没有必要使用任何setter方法,因为当我初始化类就足够时传入范围
  3. 如果将此模块保存在名为my_module.rb的文件中并运行irb命令,则可以按如下方式与您的班级进行交互:

    ➜  Code irb
    irb(main):001:0> require "#{absolute_path_to_file}/my_module"
    => true
    irb(main):004:0> include MyModule
    => Object
    irb(main):005:0> FizzBuzz.new(1..15).main
    => [1, 2, "Fizz", 4, "Buzz", "Fizz", 7, 8, "Fizz", "Buzz", 11, "Fizz", 13, 14, "FizzBuzz"]
    irb(main):006:0> FizzBuzz.new('abc').main
    TypeError: TypeError
        from /Users/username/Code/my_module.rb:6:in `initialize'
        from (irb):6:in `new'
        from (irb):6
        from /Users/alexveldtman/.rbenv/versions/2.3.1/bin/irb:11:in `<main>'
    

    更新:在再次查看代码之后,我认为重构一下这个类来摆脱那些无聊的if语句会很酷。

    module MyModule
      class FizzBuzz
        attr_reader :main
    
        def initialize(range)
          raise TypeError, 'not a Range' unless range.is_a? Range
          @main = []
          range.to_a.each do |i|
            main << fizzbuzzerize(i){|fizzy_string, k| string_or_num(fizzy_string, k) }
          end
        end
    
        private
    
        def fizzbuzzerize(num)
          yield [divisible_by_3?(num), divisible_by_5?(num)].compact.join, num
        end
    
        def string_or_num(string, num)
          (string.length > 0 ? string : nil) || num
        end
    
        def divisible_by_3?(num)
          num % 3 == 0 ? "Fizz" : nil
        end
    
        def divisible_by_5?(num)
          num % 5 == 0 ? "Buzz" : nil
        end
      end
    end
    

    注意:fizzbuzzerize方法产生一个块而不是返回值

答案 1 :(得分:0)

要回答原始问题,只需将要返回的变量放入数组:

def main
  [str_fb]
end

这里可以进行许多其他特定于Ruby的改进。对于初学者,您可以将int_numint_num=方法替换为一行:attr_accessor :int_num。 (您需要将raise移动到构造函数。)

您可以将str_fb方法替换为另一行:attr_reader :str_fb

在构造函数中,Ruby中更常见的是使用实例变量来存储输入参数。考虑哪些方法要公开,哪些方法要私有。您可以通过添加单行attr_accessor并在其下方移动这些方法来使实例方法(包括attr_readerprivate私有。

所以你的代码可能如下所示:

class FizzBuzz

  attr_accessor :int_num
  attr_reader :str_fb, :value

  def initialize(int_num, str_fb, value)
    raise TypeError unless int_num.is_a?(Integer)
    @int_num = int_num
    @str_fb = str_fb
    @value = value
  end

  <public instance methods here>

  private

  <private instance methods here>

end