iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 24
0
自我挑戰組

Codewars Ruby Challenge in 30 Days系列 第 24

Codewars Ruby Challenge - Day 24/30

學習

  1. 善用 find 方法:以題目「只有一個」符合答案,就很適合用 find 方法,find 用途是「找出符合條件的第一個值」,select 則是找出符合條件的所有值。這兩個方法在 rails 操作 ORM 很常用,反而在純 ruby 很少用而忘記有這個方法。(補充:在 ruby 中跟 find 同義字叫 detect,用法相同)
  2. 取出 Hash 第一個 key 的方法:聽起來很簡單,但實際做就是突然想不到,平常就是用到 Hash.keys 或 Hash.values 取出在 Hash 中所有的 keys 或 values,其實要只取第一個 key 就跟陣列取值一樣用「Hash.keys[0]」。
  3. group_by 與 itself 方法:這兩個方法都是第一次用,group_by 用法跟 map, select 一樣內含 yield 會去執行後面的 block,去告訴它我們需要的條件是什麼,最後回傳結果給你。下面範例說明:

如果以「是否為奇數」的條件分組

[20,1,1,2,2,3,3,5,5,4,20,4,5].group_by { |x| x.odd? }

# 結果:
{false=>[20, 2, 2, 4, 20, 4], true=>[1, 1, 3, 3, 5, 5, 5]}

說明
結果會回傳一個 hash,因為條件的結果只會有 true 或 false,所以 hash 就會把這兩個結果作為 key,陣列中的所有值再去看符合哪一組,就會變成對應 key 的 value

以這次題目為條件,希望直接拿陣列中「數值本身」作為條件

[20,1,1,2,2,3,3,5,5,4,20,4,5].group_by { |x| x.itself }

# 結果:
{20=>[20, 20], 1=>[1, 1], -1=>[-1, -1], 2=>[2, 2], -2=>[-2, -2], 3=>[3, 3], 5=>[5, 5, 5], 4=>[4, 4]}

說明
雖然就是要以「數值本身」做為條件,好像就直接 group_by 就好,但它還是需要條件,在 ruby 中 itself 的方法就是會傳「數值本身」。特別的是,因為當 Hash 中出現第二同樣名稱的 key 時,後者會蓋掉前者,所以結果才看不到重複的 key,且不影響題目答案


題目:

# Given an array of integers, find the one that appears an odd number of times.There will always be only one integer that appears an odd number of times.
# 翻譯:找出在陣列中出現次數是奇數的那個數字
def find_it(seq)

end

答案需要過以下測試:

RSpec.describe do
  it "Basic tests" do
    expect(find_it([20,1,-1,2,-2,3,3,5,5,1,2,4,20,4,-1,-2,5])).to eq(5)
    expect(find_it([1,1,2,-2,5,2,4,4,-1,-2,5])).to eq(-1)
    expect(find_it([20,1,1,2,2,3,3,5,5,4,20,4,5])).to eq(5)
    expect(find_it([10])).to eq(10)
    expect(find_it([1,1,1,1,1,1,10,1,1,1,1])).to eq(10)
  end
end

我的答案

def find_it(seq)
  seq.group_by(&:itself).select { |k, v| v.length.odd? }.keys[0]
end

思路:

  1. 轉化題目成先把陣列中的數字分類,看有幾種數字與對應的數量
  2. 想到之前有看過 group_by 的方式能達成,但沒用過整個不知道用法,查了一下資料才知道
  3. 最後卡的是,要找出第一個 hash 的 key,也是找了資料才知道像陣列的方式取

Best Practice Voted in Codewars

def find_it(seq)
  seq.find{|c| seq.count(c).odd? }
end

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

尚未有邦友留言

立即登入留言