Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
月単位でイテレーションする
Search
osyo
June 03, 2021
Programming
370
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
月単位でイテレーションする
osyo
June 03, 2021
More Decks by osyo
See All by osyo
5分で話せる Ruby 3.1
osyo
0
200
AST を使って ActiveRecord の where の条件式をブロックで記述しよう
osyo
2
1.3k
Vim の開発環境自慢
osyo
5
3.1k
Use Macro all the time ~ マクロを使いまくろ ~ 感想戦
osyo
0
340
Use Macro all the time ~ マクロを使いまくろ ~ (English)
osyo
3
450
Use Macro all the time ~ マクロを使いまくろ ~ (日本語)
osyo
0
2.3k
Ruby 3.0 で変わった private と attr_xxx
osyo
1
810
Ruby 2.0 から Ruby 3.0 を駆け足で振り返る
osyo
0
2.4k
12月25日にリリースされる Ruby 3.0 に備えよう!
osyo
1
3.5k
Other Decks in Programming
See All in Programming
symfony/aiとlaravel/boost
77web
0
120
なぜ型を書くのか? TSKaigi2026で改めて考える #tskaigi_smarthr
kajitack
0
300
Creating Composable Callables in Contemporary C++
rollbear
0
200
なぜ関数型プログラミングで「型」と「証明」が語られるのか #fp_matsuri
kajitack
3
720
「正の参照」と 「負の導出」で組む ハーネスエンジニアリング
cottpan
1
130
OS アップデート対応の取り組み方がもっと共有されてほしい
andpad
0
110
Generative UI & AI-Assistants for Your Angular Solutions
manfredsteyer
PRO
0
150
エンジニア向け会社紹介/Findy Company Profile
findyinc
6
360k
関数型プログラミングのメリットって何だろう?
wanko_it
0
150
任せる範囲はこう広がった / How the Scope of AI Delegation Has Expanded
nrslib
1
240
Honoでのサプライチェーン侵害対策 〜 3つのライブラリに学ぶ
yusukebe
7
1.8k
AI がコードを書く時代における新卒エンジニアの仕事風景 (2026) / New Graduate Engineers in the Era of AI Coding (2026)
sushichan044
0
200
Featured
See All Featured
sira's awesome portfolio website redesign presentation
elsirapls
0
300
Practical Orchestrator
shlominoach
191
11k
Typedesign – Prime Four
hannesfritz
42
3.1k
Crafting Experiences
bethany
1
210
Conquering PDFs: document understanding beyond plain text
inesmontani
PRO
4
2.9k
Introduction to Domain-Driven Design and Collaborative software design
baasie
1
890
Statistics for Hackers
jakevdp
799
230k
Agile that works and the tools we love
rasmusluckow
331
22k
We Are The Robots
honzajavorek
0
270
Helping Users Find Their Own Way: Creating Modern Search Experiences
danielanewman
31
3.2k
Principles of Awesome APIs and How to Build Them.
keavy
128
18k
Ecommerce SEO: The Keys for Success Now & Beyond - #SERPConf2024
aleyda
1
2.1k
Transcript
Omotesando.rb #63 Omotesando.rb #63 月単位でイテレーションする 月単位でイテレーションする
自己紹介 自己紹介 名前:osyo Twitter : github : ブログ : 書いたので気になる人は見
てね! @pink_bangbi osyo-manga Secret Garden(Instrumental) 趣味で気になった bugs.ruby のチケットをブログにまとめてる 令和時代の Ruby 基礎文法最速マスター
月単位でイテレーションする 月単位でイテレーションする
背景 背景 特定の Date ~ Date 間で日、月、年の日付を取得したかった 日、年の日付はシュッと取得できた 月はちょっと難しかった 今回はどうやって月単位でイテレーションする事ができたのかの思
考を追ってみる話
前提条件 前提条件 日付は1 日で固定 2020/04/01 みたに1 日で固定する 2020/04/14 みたいな日付は考慮しない 年をまたぐ可能性もあるよ
2020/04/01 ~ 2022/04/01 間 次の月は Date#next_month で取得できる require "date" puts Date.parse("2020/01/01").next_month # => 2020-02-01
Range#step でできないか考えてみる Range#step でできないか考えてみる Date は Range として扱うことができる で特定の日単位でイテレーションできる ただし、月の日数は一定ではないのでこれで対応するのは難しい
Range#step require "date" first = Date.parse("2020/01/01") last = Date.parse("2020/01/04") p (first..last).map(&:to_s) # => ["2020-01-01", "2020-01-02", "2020-01-03", "2020-01-04"] # 10 日ごとにイテレーションする first = Date.parse("2020/01/01") last = Date.parse("2020/02/01") p (first..last).step(10).map(&:to_s) # => ["2020-01-01", "2020-01-11", "2020-01-21", "2020-01-31"]
Enumerator.new で自前でイテレーションする Enumerator.new で自前でイテレーションする で任意のイテレーションを作る事ができる これを利用して月ごとにイテレーションする Enumerator.new enum = Enumerator.new
{ |y| # y << を呼ぶたびにイテレーションのブロックを呼び出す # これは 1 〜3 をブロックに渡すような例 y << 1 y << 2 y << 3 } enum.each { |it| p it } # => 1 # 2 # 3
いけるやん!!! いけるやん!!! require "date" first = Date.parse("2020/01/01") last = Date.parse("2020/04/01")
# 開始の月から終了の月までをイテレーションする enum = Enumerator.new { |y| date = first while date <= last y << date date = date.next_month end } p enum.map(&:to_s) # => ["2020-01-01", "2020-02-01", "2020-03-01", "2020-04-01"]
Enumerator.produce を使う Enumerator.produce を使う Enumerator.new を使うと実現できるがやや冗長 そこで という便利メソッドを使う これは与えられたブロックを呼び出し続ける Enumerator
を返す Enumerator.produce # 0, 2, 4, 6, 8... と無限に続ける Enumerator を定義 nums = Enumerator.produce(0) { |it| it + 2 } # take を使って先頭から4 つの要素を取り出す pp nums.take(4) # => [0, 2, 4, 6] # ランダムな要素を返す Enumerator を定義 rand = Enumerator.produce { rand(10) } # 10 個のランダムな要素を取り出す pp rand.take(10) # => [1, 1, 6, 3, 4, 0, 1, 9, 1, 1]
これを利用して月単位のイテレーションも定義する require "date" first = Date.parse("2020/01/01") last = Date.parse("2020/04/01") #
これで開始日から次の月まで永遠とイテレーションする Enumerator を定義する # これだけだと無限ループになる enum = Enumerator.produce(first) { |it| it.next_month } # 試しに先頭5 月分を取得する puts enum.take(5) # => 2020-01-01 # 2020-02-01 # 2020-03-01 # 2020-04-01 # 2020-05-01
で終了条件を指定する で終了条件を指定する Enumerator.produce だと無限ループになる を使うことで特定の条件までの要素を取得 完成!!! 完成!!! Enumerable#take_while Enumerable#take_while Enumerable#take_while
require "date" first = Date.parse("2020/01/01") last = Date.parse("2020/04/01") # take_while の条件になるまでの値を取得する result = Enumerator.produce(first, &:next_month).take_while { |date| date <= last } puts result # => 2020-01-01 # 2020-02-01 # 2020-03-01 # 2020-04-01
まとめ まとめ Enumerator.produce べんり
ご清聴 ご清聴 ありがとうございました ありがとうございました