WebEngine

だらだらと綴る技術系メモ

元弓道部、アロー関数を勉強する

f:id:web-engine:20190609234801p:plain

アロー関数に救われたい

高校時代、弓道部に所属していました。
高校に入って、部活の見学をしていたとき、先輩たちの放った矢がズドンと音を立てているのを聞いて、入部を決めました。
授業は嫌いでしたが、部活は結構楽しかったので、学校にはちゃんと行っていたのかもしれません。


時は流れ、筆者はプログラマになり、JavaScriptアロー関数と出会います。

アロー(arrow)とは、矢、もしくは矢印のこと。
) =>の部分は、弓矢に見えないこともありません。
弓道部として、親しみを覚えました。

願わくば、弓道と同じく、アロー関数が過酷なエンジニア生活に恵みをもたらしてくれることを期待します。

アロー関数の特徴

アロー関数は、大きく2つの特徴を持ちます。

  1. 短く記述できる
  2. thisの値の固定

これらを順に見ていきます。

(注意点としてIEの未対応が挙げられます)

特徴1.短く記述できる

ES6以前の書き方はこんな感じでした。
(ES6とは、2015年に標準として策定されたJSの新しい文法を指す)

const test = function(x){
    return x + x;
}


アロー関数だと、functionを省略できます。

const test = (x) => {
    return x + x;
}


さらに、関数の中身が一文だけならば、中括弧を書かなくてもOK。
returnも記述不要になります。

const test = (x) => x + x;

なんか疾走感あって好き。

2019.6.14 追記

場合によっては()すら省略できます。

// 引数が1つならば()は省略可
const test = x => x + x;
// 引数が2つ以上の場合は省略不可
const test = x, y => x + y;  // Uncaught SyntaxError: Missing initializer in const declaration
const test = (x, y) => x + y;  // OK
// 引数がない場合、省略不可
const test = () => "test";


特徴2.thisの値の固定

MDNは、この「固定」という言葉を「束縛」と表現しています。
(この「束縛」という表現ですが、MDNでは、時期によって定義が変わっていたみたいで、「束縛する」「束縛しない」の混在が見られます)


筆者が参考したなかで、わかりやすかった表現は

アロー関数式で宣言された関数は、宣言された時点で、thisを確定(=束縛)させてしまう

というものです。
引用元: 【JavaScript】アロー関数式を学ぶついでにthisも復習する話


一般的にJSでは、関数内でthisを使うと、その呼び出し元のオブジェクトとして扱われます。

// letやconstを付加していないのでグローバルとして定義されている
param = 'test';

function normalFunc() {
  console.log(this.param);
}

const hoge = {
  param: 'hoge',
  func: normalFunc
}

hoge.func();  // hoge

上記ソースコードでは、グローバルのtestではなく、オブジェクト内部で定義されているhogeが出力されました。
thisの値は、関数がコールされるときに決定され、関数を定義した段階ではthisはなにを指すか決まっていないということです。


ですが、アロー関数で定義したときに挙動は上とは違います。

// letやconstを付加していないのでグローバルとして定義されている
param = 'test';

const arrowFunc = () => console.log(this.param);

const obj = {
  param: 'hoge',
  func: arrowFunc
}

obj.func();  // test

呼び出し元のオブジェクトが存在しない状況においては、thisは、グローバルオブジェクトを指します。

param = 'test';
console.log(this.param);  // test

この状態でアロー関数を定義すると、アロー関数式で宣言された関数は、宣言された時点で、thisを固定するので、testが出力されるという理屈です。


で、アロー関数でthisが固定化されているとどんなメリットがあるのかというと

var self = this;

みたいな記述しなくて済んだりします。


裏を返せば、既存のプログラムを修正する場合などは、thisによってプログラムの挙動が違ってきますので、アロー関数に置き換える際には注意が必要になります。

まとめ

アロー関数を使えば、短く書くことができる。
ただし、thisの挙動における最低限の知識を持っていないと、その鋭利な矢先を自らに向けることなる。


参考

辞書型の基本操作【Python】

f:id:web-engine:20190608210103p:plain

辞書、ひいてますか?

授業中で調べものをするときなんかに、学生時代は辞書をよく引きました。

筆者は電子辞書を持っていなかったので、国語辞典、英和辞典、漢和辞典など、それぞれ 紙媒体の辞書をカバンに入れて登下校していました。
重かったです。

年齢を重ねてからは辞書を引くこともなくなりました。
仕事で知らない単語と出会ったときは、インターネットで検索しています。

しかし、たまにぱらぱらとめくってみると面白い発見があるものです。
学生のとき描いた落書きがあったりなんかして。


Pythonには辞書(ディクショナリ)型と呼ばれるデータの型があります。

キーとデータが組み合わせになったもので、 キーを指定して、値を参照したり、更新したりします。

環境

# python --version
# 3.5.1


以下は、コマンドライン上で検証したものです。
このような辞書を使用します。

>>> dict = {'tanaka':10, 'yasuhara':5, 'kanzaki':17}


1. 要素数の取得

構文:len(辞書)

>>> len(dict)
3


2. 対象辞書のキーをすべて取得

構文:辞書.keys()

>>> dict.keys()
dict_keys(['tanaka', 'yasuhara', 'kanzaki'])


3. 対象辞書の値をすべて取得

構文:辞書.values()

>>> dict.values()
dict_values([10, 5, 17])


4. 対象辞書のキーと値をすべて取得

構文:辞書.items()

>>> dict.items()
dict_items([('tanaka', 10), ('yasuhara', 5), ('kanzaki', 17)])


5. 指定したキーの値を取得

構文:辞書.get(キー名)

>>> dict.get('kanzaki')
17

存在しないキー名を指定するとなにも返さない。

>>> dict.get('hoge')
>>> 

筆者はこのように取得することがほとんど。

>>> dict['kanzaki']
17


6. キーの値を取得し、辞書から削除する

構文:辞書.pop(キー名)

>>> dict.pop('yasuhara')
5
>>> dict
{'tanaka' : 10, 'kanzaki' : 17}


要素を取得する必要のないときはdel(辞書[キー名])を使う。

>>> del(dict['yasuhara'])
>>>


7. 新規のキー、値の設定

構文:辞書.setdefault(キー名[, 値])
引数に入れたキー名が、辞書に登録されていない場合、新しく辞書に追加される。

>>> dict.setdefault('miyamoto', 23)
23
>>> dict
{'miyamoto' : 23, 'tanaka' : 10, 'yasuhara' : 5, 'kanzaki' : 17}

yasuharaが存在しているのは、popメソッドを使ったあと、再追加したものを使っているからです)

辞書内に登録済みのキーを設定しようとすると、その値を返します。

>>> dict.setdefault('tanaka', 9)
10


上書きしたい場合はメソッドを使わずに記述。

>>> dict['tanaka'] = 9


8.辞書のループ処理

キーを反復処理させたい場合、keys()メソッドを使用。

for key in dict.keys():
  print(key)


値を反復処理させたい場合、values()メソッドを使用。

for val in dict.values():
  print(val)


キーと値を反復処理させたい場合、items()メソッドを使用。

for item in dict.items():
  print(item)

キーと値を別々に取得したい場合。

for key, val in dict.items():
  print(key, ' : ', val)


まとめ

辞書型自体はよく使いますが、get()メソッドやsetdefault()メソッドなど覚えていないものも 多かったです。

プログラミング言語の辞書である公式ドキュメントを見直すことで発見できるので、 隙間時間に確認したいと思いました。

参考


複数の値がすべて等しいか判断したい

f:id:web-engine:20190608140805p:plain

手法

  1. 値をすべて配列に格納
  2. 値が重複しないように配列(リスト)を操作
  3. 配列(リスト)の要素数を調べる

 調べた要素数が1ならば、すべての値が等しい。

以下は、PHPPythonJavaScriptの記述です。

処理速度などは一切考慮していません。

PythonJavaScriptでは、比較しやすいようにsetを使う方法に統一しています。

PHP(5.6.3)

<?php
$a = 1;
$b = 2;
$c = 1;
$result = (count(array_unique([$a, $b, $c])) === 1) ? true : false;
var_dump($result);  // false

$b = 1;
$result = (count(array_unique([$a, $b, $c])) === 1) ? true : false;
var_dump($result);  // true

Python(3.5.1)

a = 1
b = 2
c = 1
result = True if len(set([a, b ,c])) == 1 else False
print(result)  # False

b= 1
result = True if len(set([a, b ,c])) == 1 else False
print(result)  # True

JavaScript

let a = 1;
let b = 2;
let c = 1;
const set1 = new Set([a, b, c]);
const result1 = (set1.size === 1) ? true : false;
console.log(result1);  // false

b = 1;
const set2 = new Set([a, b, c]);
const result2 = (set2.size === 1) ? true : false;
console.log(result2);  // true

参考