iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 28
0
自我挑戰組

Codewars Ruby Challenge in 30 Days系列 第 28

Codewars Ruby Challenge - Day 28/30

  • 分享至 

  • xImage
  •  

學習

  1. reject 方法:我們常常會用 select 篩選陣列中符合某條件的值,有時也會想篩選「不符合條件」,這時候就會用 !=,但其實在「不符合」這件事 ruby 有提供 reject 方法,也就是反向的 select 語意上會更直接
  2. Integer.zero? 方法:跟上面 reject 一樣,我們在判斷值是否是 0,可以用 == 0 也不算難懂,但如果用 zero? 語意上一樣會更直接
  3. 多行鏈結:這算是 Coding Style 的部分,也是從助教 DC 那邊學到的,出社會後很多團隊其實會規範程式碼單行最多 80~120 字元,為了讓程式碼更好閱讀(有文章詳細說明),所以當 method chain 過長時,適時換行就是個好習慣,幫助自己與團隊閱讀。(下面範例說明)

如果今天的答案一路 chain 下去

num.to_s.split("").map.with_index { |n, i| n + '0' * (num.to_s.length - i - 1)}.select { |n| n.to_i != 0 }.join(" + ")

說明:閱讀上超難看懂用了哪些方法

如果今天的答案用「多行鏈結」好的 coding style

num.to_s
   .split("")
   .map
   .with_index { |n, i| n + '0' * (num.to_s.length - i - 1)}
   .select { |n| n.to_i != 0 }
   .join(" + ")

說明:上面提供的參考文章有提到「比起橫向閱讀,人更擅長縱向閱讀」,很明顯這樣的寫法很好看清楚程式流程、用了哪些方法


題目:

You will be given a number and you will need to return it as a string in Expanded Form. For example:
expanded_form(12); # Should return '10 + 2'
expanded_form(42); # Should return '40 + 2'
expanded_form(70304); # Should return '70000 + 300 + 4'

# 翻譯:把 input 的數字拆成各分位的相加 ex. 12 -> '10 + 2'

def expanded_form(num)
end

答案需要過以下測試:

RSpec.describe "Write Number in Expanded Form" do
  it "Example cases" do
    expect(expanded_form(12)).to eq('10 + 2')
    expect(expanded_form(42)).to eq('40 + 2')
    expect(expanded_form(70304)).to eq('70000 + 300 + 4')
  end
end

我的答案

def expanded_form(num)
  num.to_s
     .split("")
     .map
     .with_index { |n, i| n + '0' * (num.to_s.length - i - 1)}
     .select { |n| n.to_i != 0 }
     .join(" + ")
end

思路:

  1. 這題一開始想了幾種解法,但發現只有一種我能看得到出口的曙光 XD 就決定採用下面的思考方式
    • input 的數字拆成一個個字元放入陣列
    • [1, 2] -> a[0]+ '0' * (a.length -1), a[1]+ '0' * (a.length - 2)
    • 最後再組合起來
  2. 先把 input 變成陣列字串,好一個個看個別要補多少 0 給它,針對都是 0 的去除掉,最後再用 join 合其來
  3. 雖然可以一行寫完,學習把可以 chain 的拆成多行

Best Practice Voted in Codewars

def expanded_form(num)
  num.to_s
     .chars
     .reverse
     .map.with_index { |d, idx| d.to_i * 10**idx }
     .reject(&:zero?)
     .reverse
     .join (' + ')
end

上一篇
Codewars Ruby Challenge - Day 27/30
下一篇
Codewars Ruby Challenge - Day 29/30
系列文
Codewars Ruby Challenge in 30 Days30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言