fkm 〜 Super Software Entertainerへの道 〜 このページをアンテナに追加 RSSフィード

 

2018-02-05 JavaScriptのGenerator関数

[][]JavaScriptのGenerator関数 JavaScriptのGenerator関数を含むブックマーク

JavaScriptには処理を途中まで実行し、値をreturnすることのできるGenerator関数定義することができる。

これがあると便利なのはゲームキャラクターを動かす時。例えば「右に10フレーム移動して下に5フレーム動く」という動きはこんな感じで書ける。

class Point {
  constructor(x, y) {
    this.x = x;
    this.y = y;
  }
}
// Generator関数はfunction* で定義する
// アロー(=>)では定義できない(たぶん
function* move(p) {
    for (var i = 0 ; i < 10 ; i++) {
        ++p.x;
        yield p;
    }
    for (var i = 0 ; i < 5 ; i++) {
        ++p.y;
        yield p;
    }
}

使うときはこんな感じ。ゲームなので1フレーム分移動したら描画しないといけない点に注意。例としてconsole.log()で出してみる。

var p = new Point(3, 4);
var m = move(p);

// 100フレーム動かす
for (var i = 0 ; i < 100 ; i++) {
    let out = m.next();
    if (out.done) break;
    console.log(p);
}

Generator関数を呼んだ戻り値に対し、next()を呼ぶと、yieldが出てくるまで処理を実行してくれる。次にnext()を呼ぶと、yieldの続きから実行してくれる。関数実行が終わっていたら、next()の戻り値のdoneフィールドがtrueになってる。

f:id:fkm:20180205012626p:image

ひとつ別な例。ずっと1を出力しつづけるGenerator関数定義してみる。

function* get1() {
    while (true) yield 1;
}

これを10回呼んでみる。yieldの結果は、next()の戻り値valueフィールドに入っている。

var n = get1()
for (var i = 0 ; i < 10 ; i++) {
    console.log(n.next().value);
}

もちろんコンソールには1が10個表示される

トラックバック - http://d.hatena.ne.jp/fkm/20180205

2018-02-04 Kotlinでリストの中身を連結した文字列を作る

[][]Kotlinリストの中身を連結した文字列を作る Kotlinでリストの中身を連結した文字列を作るを含むブックマーク

Kotlinは1つのことをやるのに、いろんな書き方ができてしまう、困った言語Goに比べて)

ということで今回のテーマは、「リストの中身を連結したい」

基準となるコードはこんな感じ。

fun main(args: Array<String>) {
    val numbers = (1..10000).map{ Integer.toString(it) }.toList()
    val before = System.currentTimeMillis()

    // ここで連結処理

    val after = System.currentTimeMillis()
    print("time ")
    println(after - before)
}

Javaっぽくforで

val buffer = StringBuilder()
for (n in numbers) {
    buffer.append(n)
}

素数を1000万にして、手元のMBP 2015で2秒程度。

forEach

コレクションに対してはforEachが使えるんでした。

val buffer = StringBuilder()
numbers.forEach {
    buffer.append(it)
}

こちらも、要素数を1000万にして2秒程度。forとほぼ同じですな。

reduce

コレクションの要素を足していく用途としてreduceというのもありました。

val str = numbers.reduce { acc, s -> acc + s }

単純な文字列の足し算しちゃってるので、速度的にもやばそう。予想通り、10万要素で9秒。

joinTo

要素をくっつける用のメソッドがあったりする。

val buffer = StringBuilder()
numbers.joinTo(buffer = buffer, separator = "")

速度は、1000万要素で2秒程度。StringBuilderでくっつけてるので、早い。

joinToString

もう少し短くかけるメソッドまで用意されてたりする。

val str = numbers.joinToString(separator = "")

速度は1000万要素で2秒程度。

まとめ

いろんな書き方がありすぎなんじゃ。。。

トラックバック - http://d.hatena.ne.jp/fkm/20180204

2017-12-15 JavaScriptのasync/awaitを試す

[][]JavaScriptのasync/awaitを試す JavaScriptのasync/awaitを試すを含むブックマーク

サンプルコードを書いてる方が多いものの、なんかわかりにくいものが多かったので自分用にまとめ。

async関数

結果を非同期で返す関数になる。つまりPromiseを返す関数になる。TypeScriptだと、こんな感じ。

async function getMokeName() : Promise<string> {
    return 'moke001';
}

Promiseじゃない値を戻り値の型にすると、怒られる。

$ tsc --locale ja -target esnext app.ts
app.ts(2,28): error TS1064: 非同期関数または非同期メソッドの戻り値の型は、グローバル Promise<T> 型である必要があります。

asyncがついてるけど、結局はPromiseを返す関数なので、使い方はやっぱりPromise

getMokeName().then((name : string) => {
    console.log(name);
});

await

awaitは、Promiseが結果を返すまで待つ。なので先ほどのasync関数を呼び出すコードは次のように書ける。

// 注:トップレベルではコンパイルエラー。次の段落を読んでね
let name = await getMokeName();
console.log(name);

ただしawaitはasync関数内でしか使えない。 なのでasync関数で包む。

async function doSomething() {
    let name = await getMokeName();
    console.log(name);
}

Promiserejectを返すと?

awaitで待ってる箇所では普通例外になる。なので次のようにtry-catchで拾う。

async function doSomething() {
    try {
        let name = await getMokeName();
        console.log(name);
    } catch (e) {
        console.log('error!' + e);
    }
}

try-catchがなかった場合はどうなるか?awaitを使ってるのはasync関数内なので、要するにPromisecatch()で拾えばよい。

async function doSomething() {
    let name = await getMokeName();
    console.log(name);
}

doSomething().catch((e : any) => {
    console.log('error!! ' + e);
});
トラックバック - http://d.hatena.ne.jp/fkm/20171215

2017-12-02 クソアプリ Advent Calendar 2017

[]クソアプリ Advent Calendar 2017 クソアプリ Advent Calendar 2017を含むブックマーク

書けという圧を受けたので書いてみます。これの2日目です。

個人アプリ出してた時期のは、ほんとひどいアプリが多い。その中でも今回はこれ。

fkm basic

オレオレ仕様BASICなので、fkm basicとしてみました。アプリ自体はなつかしのBASICプログラムを書いて実行できるというもの

何がクソアプリかというと

FORループがない

そして

GOSUBもない

LINEとかCIRCLEとかの描画系命令もちろんありません

文字通りのクソアプリですが、次をご覧ください。

f:id:fkm:20171201205511p:image

なぜかインド方面大人気です

現場からは以上です

2017-08-12 emacs lispでKii CloudのAPIを叩く

[][]emacs lispでKii CloudのAPIを叩く emacs lispでKii CloudのAPIを叩くを含むブックマーク

備忘録として。

(setq url-request-method "POST")
(setq url-request-extra-headers '(("Content-Type" . "application/json")
                                  ("x-kii-appid" . "<APP_ID>")
                                  ("x-kii-appkey" . "<APP_KEY>")))
(setq url-request-data "{\"username\":\"demo\",\"password\":\"123456\"}")

(url-retrieve "https://api-jp.kii.com/api/oauth2/token"
              (lambda (status) (switch-to-buffer (current-buffer))))

結果は別バッファに表示される。こいつをパースするのは自力でなんとかするのかな。。?

トラックバック - http://d.hatena.ne.jp/fkm/20170812