2017-10-17 101 views
0

我想做我的作業,我想問你是否可以幫助我寫一個Ruby Proc返回數字(Integer ,Float ...)和數字字符串(「22」)乘以2和文本字符串(「sos」)只是返回不變。我試圖用一元運算符做到這一點,但我不使用Float。Ruby Proc返回數字和數字字符串乘以2作爲未受騙的類型和文本strng只是返回

def make_double 
    proc = Proc.new { |x| (x.is_a? Integer or x !~ /\D/) ? ((x.to_i)*2).to_s : x } 
end 

有沒有可能如何在proc中編寫更復雜的條件?謝謝

+0

對不起,我有點失去了,究竟是什麼你期望這個來做。也許有幾個示例輸入/輸出可能有幫助?另外,你是否有理由把它壓縮到一行?我認爲問題肯定在你的x!〜/ \ D /中。 '.to_i'也需要從它的聲音中成爲'.to_f'。我認爲你應該檢查出http://rubular.com/的正則表達式,但可能像'\ d +(?:\。\ d +)?'? – user3334690

+0

我只需要這個例如 –

+0

p = make_double ;;; p.call(42) - > 84 ;;; p.call(42.0) - > 84.0 ;;; p.call(「42」) - >「84.0」;;; p.call(「Universe」) - >「Universe」;;; 並且必須使用Proc –

回答

2

易讀

puts '-- do block --' 

def make_double 
    Proc.new do | x | 
     case x 
     when Integer, Float then x * 2 
     when String 
      if x =~ /\d/ 
      then (x.to_i * 2).to_s 
      else x 
      end 
     else 
      "Invalid class #{x.class.name} for x." 
     end 
    end 
end 

puts "42 -> #{make_double.call(42)}  #{make_double.call(42).class}" 
puts "42.0 -> #{make_double.call(42.0)} #{make_double.call(42.0).class}" 
puts "'42' -> #{make_double.call('42')}  #{make_double.call('42').class}" 
puts "'xyz' -> #{make_double.call('xyz')} #{make_double.call('xyz').class}" 
puts "4..8 -> #{make_double.call(4..8)}" 

執行:

$ ruby -w t_a.rb 
-- do block -- 
42 -> 84  Integer 
42.0 -> 84.0 Float 
'42' -> 84  String 
'xyz' -> xyz String 
4..8 -> Invalid class Range for x. 

難以閱讀

puts '-- brace block --' 

def make_double 
    Proc.new { | x | x.is_a?(Integer) || x.is_a?(Float) ? x * 2 : \ 
     x.is_a?(String) ? x =~ /\d/ ? (x.to_i * 2).to_s : x : 'invalid' } 
end 

puts "42 -> #{make_double.call(42)}  #{make_double.call(42).class}" 
puts "42.0 -> #{make_double.call(42.0)} #{make_double.call(42.0).class}" 
puts "'42' -> #{make_double.call('42')}  #{make_double.call('42').class}" 
puts "'xyz' -> #{make_double.call('xyz')} #{make_double.call('xyz').class}" 
puts "4..8 -> #{make_double.call(4..8)}" 

執行:

$ ruby -w t.rb 
-- brace block -- 
42 -> 84  Integer 
42.0 -> 84.0 Float 
'42' -> 84  String 
'xyz' -> xyz String 
4..8 -> invalid 
+0

是的,這工作正常,謝謝! –

+0

'make_double.call(「42.5」)怎麼樣'不確定是否這種情況。我想你也可以節省一些時間,把所有事情都做成一個字符串。就像:'(x.to_s =〜/ \d+(?:\.\d+)?/)? x.to_f * 2:x' – user3334690

+1

@ user3334690對!由於OP沒有問,我沒有測試過,我的'如果x =〜/ \ d /'不夠。添加了更完整的答案。 – BernardK

1

這個答案考慮從@ user3334690的評論,並糾正錯誤的結果

puts "'42xyz' -> #{make_double.call('42xyz')} #{make_double.call('42xyz').class}" 
puts "'x42y' -> #{make_double.call('x42y')}  #{make_double.call('x42y').class}" 
puts "'42.5' -> #{make_double.call('42.5')} #{make_double.call('42.5').class}" 

這是

'42xyz' -> 84 String 
'x42y' -> 0  String 
'42.5' -> 84 String 

一個班輪

puts '-- brace block 2 --' 

def make_double 
    Proc.new { | x | (x.to_s =~ /\d+(?:\.\d+)?/) ? x.to_f * 2 : x rescue puts "Error" } 
end 

puts "42 -> #{make_double.call(42)}   #{make_double.call(42).class}" 
puts "42.0 -> #{make_double.call(42.0)}   #{make_double.call(42.0).class}" 
puts "'42' -> #{make_double.call('42')}   #{make_double.call('42').class}" 
puts "'42xyz' -> #{make_double.call('42xyz')}  #{make_double.call('42xyz').class}" 
puts "'x42y' -> #{make_double.call('x42y')}  #{make_double.call('x42y').class}" 
puts "'42.5' -> #{make_double.call('42.5')}  #{make_double.call('42.5').class}" 
puts "'42.5xyz' -> #{make_double.call('42.5xyz')} #{make_double.call('42.5xyz').class}" 
puts "'xyz' -> #{make_double.call('xyz')}   #{make_double.call('xyz').class}" 
puts "4..8 -> #{make_double.call(4..8)}" 

執行:

$ ruby -w t_short2.rb 
-- brace block 2 -- 
42 -> 84.0   Float 
42.0 -> 84.0   Float 
'42' -> 84.0   Float 
'42xyz' -> 84.0  Float 
'x42y' -> 0.0  Float 
'42.5' -> 85.0  Float 
'42.5xyz' -> 85.0 Float 
'xyz' -> xyz   String 
Error 
4..8 -> 

請注意,包含數字的所有數字和字符串均轉換爲浮點數,'x42y'轉換爲0.0。

保持原班

字符串混合數字和字母不會轉換(使用錨^和$的正則表達式)。

puts '-- do block 2 --' 

def make_double 
    Proc.new do | x | 
     case x 
     when Integer, Float then x * 2 
     when String 
      case 
      when x =~ /^\d+\.\d+$/ then (x.to_f * 2).to_s 
      when x =~ /^\d+$/  then (x.to_i * 2).to_s 
      else x 
      end 
     else 
      "Invalid class #{x.class.name} for x." 
     end 
    end 
end 

puts "42 -> #{make_double.call(42)}    #{make_double.call(42).class}" 
puts "42.0 -> #{make_double.call(42.0)}   #{make_double.call(42.0).class}" 
puts "'42' -> #{make_double.call('42')}   #{make_double.call('42').class}" 
puts "'42xyz' -> #{make_double.call('42xyz')}  #{make_double.call('42xyz').class}" 
puts "'x42y' -> #{make_double.call('x42y')}  #{make_double.call('x42y').class}" 
puts "'42.5' -> #{make_double.call('42.5')}  #{make_double.call('42.5').class}" 
puts "'42.5xyz' -> #{make_double.call('42.5xyz')} #{make_double.call('42.5xyz').class}" 
puts "'xyz' -> #{make_double.call('xyz')}   #{make_double.call('xyz').class}" 
puts "4..8 -> #{make_double.call(4..8)}" 

執行:

$ ruby -w t_b.rb 
-- do block 2 -- 
42 -> 84    Fixnum 
42.0 -> 84.0   Float 
'42' -> 84   String 
'42xyz' -> 42xyz  String 
'x42y' -> x42y  String 
'42.5' -> 85.0  String 
'42.5xyz' -> 42.5xyz String 
'xyz' -> xyz   String 
4..8 -> Invalid class Range for x.