私が歌川です

@utgwkk が書いている

JavaScriptで [0, 1, ..., N - 1] という配列を得る

小ネタです。

課題

JavaScriptで [0, 1, ..., N - 1] みたいな、要素数Nの配列が欲しくなった。本番環境に使う用のコードではなく、とりあえず開発用に動けばよい、ぐらい。

new Array(N) で長さNの配列が得られるから、mapすれば得られるはず……と思って new Array(N).map((_, i) => i) って書いたけどうまくいかなかった。得られるのは length がNの配列で、要素は詰まっていないみたいな感じ。

> new Array(10)
[ <10 empty items> ]
> new Array(10).map((_, i) => i).forEach((x, i) => console.log(i. x))
undefined

MDNを見るとそれっぽいことがそれとなく書いてあった。言われてみれば確かに、とは思うもののびっくりする。

arrayLength
Array コンストラクターに渡された唯一の引数が 0 から 232-1 の間 (両端を含む) の整数であった場合は、新しい JavaScript の配列を返し、その length プロパティがその値になります (注: これは arrayLength 個の空のスロットを持つ配列であり、実際に undefined の値が入ったスロットではありません)。この引数がそれ以外の数値であった場合は、 RangeError 例外が発生します。

developer.mozilla.org

実現方法

fillする

要素が詰まってないので詰めましょう、みたいな感じ。なんでもよいので .fill(0) とかするとタイプ数が減る。

> new Array(10).fill(0).map((_, i) => i)
[
  0, 1, 2, 3, 4,
  5, 6, 7, 8, 9
]

なんとしてでも要素数Nの配列を作る

mapするところは同じだけど、要素数Nの配列を作るために文字列をrepeatしてspreadする。

> [...'a'.repeat(10)].map((_, i) => i)
[
  0, 1, 2, 3, 4,
  5, 6, 7, 8, 9
]

Array.from を使う

Slackでこの方法を教えてもらった。fillするよりもこっちの方がもうちょっと素直そう。

> Array.from(new Array(10), (_, i) => i)
[
  0, 1, 2, 3, 4,
  5, 6, 7, 8, 9
]

developer.mozilla.org

rangeを得るメソッドのproposalがある

NumberBigInt に、範囲を表すイテレータを返すメソッドを生やすproposalがあることを教えてもらった。使い心地はちょうどPythonの range 関数みたいな感じ。polyfillもある。

github.com

[...Number.range(100)] みたいに書くと所望の配列を得られそう。

Kindleポイント半額還元キャンペーンで買った漫画

百合姫コミックス向けのキャンペーンが行われているのかと思ったけど、そういうわけではなかった。

ふたりエスケープ

顔が良い無職の先輩と漫画家の後輩が二人で現実逃避をしまくる。いきなり生ハムの原木を買ったり、〆切直前に北陸旅行に行ったりする。頑張る自分へのご褒美も、単なる逃避もある。全力で逃げるのがいい。

「白いワンピースを着た乙女」という夏の共通幻想はどこから生まれたのだろうか。

徒然日和

のんびりした日常の中に甘いひとときがある。それは子どもも大人もそうなのだろう。夏を満喫したい気がしてきた。

電車のことを汽車と呼んだことがない。

アルコール百合アンソロジー・ストロング!

ストロング缶は最近ぜんぜん飲んでない。2週間ぐらい飲酒してなくてかつてない出来事だと思う、急に個人の日記になってすいません。

ユリキュール アルコール百合アンソロジー

ストロング! に比べてマイルドかというと、必ずしもそういう話ばかりではなかった。

Fitbit Charge 4を買った

blog.utgw.net

画面が暗すぎて心拍数も確認できなくなっていたので、Fitbit Charge 4を買ってセットアップした。付け心地はそんなに変わらない。

時間が確認できるようになって非常に便利。

「リーダブルコード」を読み直した

4年ぐらい前に読んだけど、図書館で借りたか売ってしまったかで手元になかったので、買い直して読んだ。内容としては大体納得できるけど、4年前に同じ本を読んだかどうかが怪しい。ちゃんと読めてなかったか、現実の例をいくつか見たので解像度が高まった?

空白を入れてコードを整形しましょう、みたいなことは、現代だとコードフォーマッタに一任すればよいと思う。そうすれば一貫性も担保される。コードを整形する根拠・狙いを分かっておくのはよさそう。

定期的にAPIドキュメントを読みましょう、ということが書いてあって、良い話だった。実装方針が分かってゴリッと実装してしまうけど、ライブラリを使えば同様の処理が1行で書ける、という場面はよくある。最小のコードで最大の効率を出すために、手数を増やすことを怠らないようにしたい。

本質的なことに集中できるようなコードを書けるとよい、という理解をした。そのための手段とか指針が示されているのが「リーダブルコード」という本なのだろう。あちこちのコードを読まないと本質を読み解けないようなコードになっているのと、本質的でない部分が適切に隠蔽されているのとは別だと思う。

全然関係ないけど、「本質だけが欲しいの それ以外はまやかし」みたいな言葉を聞いたことがある。何かの歌詞だと思うけど出典が分からないので、誰か知ってたら教えてください。

2021/5/16 18:49 追記

どうやら歌詞ではないことが分かった。

ピタゴラスの定理により、各色の面積はずっと同じ

↑を再現したくて失敗したけど諦めきれずに再チャレンジした。

blog.utgw.net

f:id:utgwkk:20210516022051p:plain
完成した

素朴に実装したら動作がめっちゃ重たく、ブラウザの反応が一瞬なくなったけど、 ctx.fillStyle への代入をできるだけ減らしたらすごく軽くなった。 requestAnimationFrame でアニメーションさせても平気。びよんびよんなって愉快。

gyazo.com

↓ここでアニメーションしてる様子を眺められる。コードはglitchに置いてあるので好きにremixできる。

Pytagorean squares

正方形の頂点の座標をコメントに埋め込んでいるのがみどころです。何度傾けたらよいのかも試行錯誤してて、全く計算が合わなくて大変だった。ここまで三角関数と向き合ったのはフーリエ解析の講義以来だと思う。

/*
 * (x-rsinθ, y-rcosθ) +-----+ (x+r(cosθ-sinθ), y-r(cosθ+sinθ))
 *                    |     |
 *                    |     |
 *                    |     |
 *                    |     |
 *                    |     |
 *             (x, y) +-----+ (x+rcosθ, y-rsinθ)
 */

これは図形の作り方を考えているときのスケッチ。左下の点から対角線に向かうのか、右下から向かうのか、みたいなイメージで実装したらできた。座標軸の向きがちょっと違ったり、回転させるのがうまくいかなかったりして大変だった。

f:id:utgwkk:20210516022800j:plain

canvasの最適化の方法はMDNに書いてある。 けど ctx.fillStyle に代入するのが明らかに支配的だったので、まずそこを見直すのがよいと思う。

developer.mozilla.org

2021/5/16 11:05 追記

この図形にはピタゴラスの木という名前が付いていることを知った。

ja.wikipedia.org