iT邦幫忙

2022 iThome 鐵人賽

DAY 3
0
Modern Web

clojure 刷刷鍋系列 第 3

Clojure 肉片 -第 3 塊

  • 分享至 

  • xImage
  •  

【心得】

  1. 只是 codewar 8kyu 就寫了 2hr 才寫出來,吃個火鍋肉片好不容易~~~但寫出來好感動XDD沒時間研究大大們答案的解法啊~
  2. 發現太常用寫 rails 的習慣在 define method 裡把想做的邏輯分成好幾段處理,一個做完就先暫存放進一個變數,各自做完要做的再做別的處理,看大大們常常都是能把資料一路往後丟就能完成,蠻想學習的
  3. 第一次在 Codewar 遇到 clojure 少括號的 error msg(如下圖),找了半小時才發現,怎麼 debug 這個部分要再找大大問一下

  1. 學到 clojure 世界怎麼用 index 拿出 vector 中的值(如下)
;; 原本找了很久才知道的,跟 ruby 不一樣,不能直覺的 [1, 2, 3][2] QQ

([1 2 3] 2) => 3

;; 但發現如果給的 index 超過範圍會噴 error 而不是預期的 nil

([1 2 3] 3) => IndexOutOfBoundsException: null

;; 這時候就可以用 get

(get [1 2 3] 3) => nil
  1. .indexOf 可以找出給的值對應在 vector 中的 index / (into [] xxx) 的寫法可以做到 convert list or map into vector 效果

【今日湯底】

Given a sequence of items and a specific item in that sequence, return the item immediately following the item specified. If the item occurs more than once in a sequence, return the item after the first occurence. This should work for a sequence of any type.

When the item isn't present or nothing follows it, the function should return nil in Clojure and Elixir, Nothing in Haskell, undefined in JavaScript, None in Python.

(next-item (range 1 10000) 7) ;=> 8
(next-item ["Joe" "Bob" "Sally"] "Bob") ;=> "Sally"

(必須通過以下測試)

(ns lazy-next-test
  (:require [clojure.test :refer :all]
            [lazy-next :refer [next-item]]))

(deftest SampleTests
  (is (= (next-item (range 1 25) 12) 13))
  (is (= (next-item "testing" \t) \e))
  (is (nil? (next-item [:a :b :c] :d)))
  (is (nil? (next-item [:a :b :c] :c))))

【我的答案】

(ns lazy-next)

(defn next-item
  [xs item]
  (let [to-vector (into [] xs)
        first-match-index (.indexOf  to-vector item)
        next-item (if (= -1 first-match-index) nil (get to-vector (inc first-match-index)))]
    next-item
   )
  )

思路:

  1. 把任何給的 xs 都先轉成 vector 結構(後面好用 index 去抓 next-item)
  2. .indexOf 去找第一個符合值對應的 index
  3. 有了前一點的 index 就能去找 next-item 拉
  4. 處理特殊情境:(1) 一開始給的 item 就不在 xs 內 (2) 給的 item 在 xs 內,但是在最後一個位置,不會有 next-item

【其他人的答案】

wt......好強...function 幾乎都沒看過

(ns lazy-next)

(defn next-item
  "Returns the value that comes after item in xs or nil"
  ([xs item]
  (second (drop-while (complement #{item}) xs))))
(ns lazy-next)

(defn next-item [xs item] 
   (when (not-empty xs)
       (if (= item (first xs))
            (second xs)
            (next-item (rest xs) item))))

上一篇
Clojure 肉片 -第 2 塊
下一篇
Clojure 肉片 -第 4 塊
系列文
clojure 刷刷鍋30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言