Panda Noir

JavaScript の限界を究めるブログでした。最近はいろんな分野を幅広めに書いてます。

データベースの正規化について超絶わかりやすくまとめてみた

わかりやすい(自称)です。

はじめに

この記事でわかること

  • 第一〜第五正規形+ボイスコット正規形のカンタンな説明

この記事ではわからないこと

  • 厳密な正規形の定義
  • 各正規形がなぜ必要なのか
続きを読む

Goのコードは読みにくい

基本的に人間はFの字で文を読もうとします。そのため、重要情報は縦で揃えると読みやすくなります。

最悪な点: if文を無視して読むことが出来ない

Goでは以下のような構文が頻出します。

if err := hoge(); err != nil {
}

次の問題をこの構文は抱えています。

  1. if文なのに条件式のところが処理になってしまっている
  2. err != nilerr == nilで意味が真逆になってしまうので、最後まで読まなければ意図がつかめない

通常、if文は飛ばしならが読むことが出来ます。なぜなら、リーダブルにコードを書くと、if文は「ある特定のパターンのときのみ処理する」ように書けるからです。特定パターンのとき以外、if文を読む必要がないということです。

しかし、Goの場合はif内に処理が組み込まれてしまいます。そのため、水平に最後までifを読まなければならず、読むスピードがガクッと下がります。

良い点: 型を後ろに書ける

最悪な点を先に書きましたが、Goの構文にはいいところもあります。最高な点ではないのが残念ですが。

var x float32 = 1
func fuga(n Network) {
}

重要な情報(変数名)が先で、修飾語(型)が後ろに置いてあるので、流れるように読むことが出来ます。

ちょっとフックがあれば知ってるけど、意外と知らないJavaScript技術

JavaScript技術は10年前とは比較にならないほど膨大で緻密になっています。それらはアンテナを張っていなければ見落としてしまいます。今回はそんな技術の一端を紹介します。

紹介する技術たち

  • Web Worker + Service Worker
  • SharedArrayBuffer + Atomics API
  • manifest.json
  • WebRTC
  • WebSocket
  • SIMD.js
  • WebAssembly(wasm), asm.js

それぞれについて簡単に解説をしています。さらに深く知りたい方はおすすめ記事を参照ください。

続きを読む

隣接するマスへの差分の配列をワンライナーで生成する

初めに言っておくと、数式が覚えられないくらい複雑なので実用性はありません。これが簡単な数式だったらまだ使えたのですがね…普通に[[0,1],[1,0],[0,-1],[-1,0]]のように地道に書いたほうが早いです。

用途としては、forループ内で配列を使わないで生成ができるくらいです。

隣接マスまでの差分とは?

(x,y)にいたとして、(x-1,y)(x+1,y+1)のような座標のことです。8近傍は斜めを含み、4近傍は含みません。

ソースコード

console.log([...Array(9)].map((_, i) => [(i/3|0)-1,i%3-1])); // 8近傍(現在のマスを含む)
console.log([...Array(4)].map((_, i) => [(i-2)*(i%2),(i-1)*(1-i%2)])); // 4近傍(現在のマスは含まない)
console.log([...Array(5)].map((_, i) => [(i-2)*(i%2),(i-2)/2|0])); // 4近傍(現在のマスを含む)

以下のような配列が得られます。

[[-1,-1],[-1,0],[-1,1],[0,-1],[0,0],[0,1],[1,-1],[1,0],[1,1]]
[[0,-1],[-1,0],[0,1],[1,0]]
[[0,-1],[-1,0],[0,0],[1,0],[0,1]]

forと組み合わせて使う

for(let i = 0; i < 9; i++)
    const [dx, dy] = [(i/3|0)-1,i%3-1]; // 8近傍(現在のマスを含む)

for(let i = 0; i < 4; i++)
    const [dx, dy] = [(i-2)*(i%2),(i-1)*(1-i%2)]; // 4近傍(現在のマスは含まない)

for(let i = 0; i < 5; i++)
    const [dx, dy] = [(i-2)*(i%2),(i-2)/2|0]; // 4近傍(現在のマスを含む)

実用的なソース

console.log([[-1,-1],[-1,0],[-1,1],[0,-1],[0,0],[0,1],[1,-1],[1,0],[1,1]]);
console.log([[0,-1],[-1,0],[0,1],[1,0]]);
console.log([[0,-1],[-1,0],[0,0],[1,0],[0,1]]);
for(let i = 0; i < 9; i++)
    const [dx, dy] = [[-1,-1],[-1,0],[-1,1],[0,-1],[0,0],[0,1],[1,-1],[1,0],[1,1]][i]; // 8近傍(現在のマスを含む)

for(let i = 0; i < 4; i++)
    const [dx, dy] = [[0,-1],[-1,0],[0,1],[1,0]][i]; // 4近傍(現在のマスは含まない)

for(let i = 0; i < 5; i++)
    const [dx, dy] = [[0,-1],[-1,0],[0,0],[1,0],[0,1]][i]; // 4近傍(現在のマスを含む)

解説

8近傍はみたままなので解説をしません。トリッキーなことをしている残り2つを解説します。

4近傍で得たいもの

4近傍では以下のような配列を得たいです。

[[0,-1],
[-1,0],
[0,1],
[1,0]]

コレを見ると、偶数、奇数のところが0になっていることがわかります。というかそうなるように並べたんですが。

ということは[index%2,1-index%2]としてやればつぎのような配列が得られます。

[[0,1],
[1,0],
[0,1],
[1,0]]

あとはindexが2未満のとき-1、indexが2以上のとき1をかけてやれば完成ですね。ただ、こうなるよう数式をいじるのは意外とめんどくさいので以下で代用しました。

  • iが1のとき-1、iが3のとき1を得られるi-2
  • iが0のとき-1、iが2のとき1を得られるi-1

現在のマスを含むパターン

現在のマスを含むほうは得る順番を若干変えることで数式をカンタンにしています。

[[0,-1],
[-1,0],
[0,0],
[1,0],
[0,1]]

真ん中が[0,1]から[0,0]になっています。こうすると、y座標の差分がカンタンに求めることができるようになります。

graphql-go入門

graphql-goの入門記事が全く出てこなくて苦しみ悶えながらようやく理解できたので、ここに戦いの記録を残しておこうと思います。

今回の環境

今回はMongoDB+GraphQLという構成にしました。

成果物をここにまとめましたので、参照ください。 github.com

GraphQLとは?

そもそもGraphQLとはナニカ、ですがGraphQLはクエリ言語で、APIサーバーで使われます。

たとえばつぎのようなリクエストを送ってみます。

query {
    shop(name: "ラビットハウス") {
        name
        members {
            name
        }
    }
}

すると以下のようなデータが返ってきます。

{
    "data": {
        "shop": {
            "name": "ラビットハウス",
            "members": [
                {"age":16,"name":"保登心愛"},
                {"age":14,"name":"香風智乃"},
                {"age":17,"name":"天々座理世"}
            ]}
    }
}
続きを読む