この記事のハイライト
- const reverseMap = Object.fromEntries(Object.entries(greetingMessageMap).map(a => a.reverse()))
+ const reverseMap = Object.fromEntries(Object.entries(greetingMessageMap).map(([key, value]) => [value, key]))
以上
批判・反論記事ではありません
いつも我々を楽しませてくれる記事をたくさん投稿してくれているやめ太郎氏、先日 Twitter にてこのような投稿が。
内容は書いてある通りで、「key と value が逆になったオブジェクトを作る」ためのスニペットです。
シンプルにワンライナーで使えて、とても役に立つ TIPS ですが、自分だったらこう書くかなーという部分があったので記事にしてみました。
まず、件のスニペットがこちら。このコードがどのような処理を行っているのか、紐解いてみます。
const reverseMap = Object.fromEntries(Object.entries(greetingMessageMap).map(a => a.reverse()))
こちらが元となるオブジェクトです。
const greetingMessageMap = {
morning: "おはよう",
afternoon: "こんにちは",
evening: "こんばんは"
}
① Object.entries
まず Object.entries メソッドを使って、オブジェクトを key と value の配列に変換します。
const entries = Object.entries(greetingMessageMap)
console.log(entries)
> [
> [ 'morning', 'おはよう' ],
> [ 'afternoon', 'こんにちは' ],
> [ 'evening', 'こんばんは' ]
> ]
morning: "おはよう" が [ 'morning', 'おはよう' ]、さらにそれを囲う {} が [] となり、オブジェクトから配列(配列の配列)に変換されていることがわかります。
② Array.prototype.map, Array.prototype.reverse
次に、map メソッドと reverse メソッドを使い、key と value を入れ替えます。
const reverse = entries.map(a => a.reverse())
console.log(reverse)
> [
> [ 'おはよう', 'morning' ],
> [ 'こんにちは', 'afternoon' ],
> [ 'こんばんは', 'evening' ]
> ]
もともとの配列では [ 'morning', 'おはよう' ]([ key, value ]) となっていたものが [ 'おはよう', 'morning' ]([ value, key ])となっており、key と value が入れ替わっているということがわかります。
自分だったら
今回「自分だったらこう書くかなー」と思った部分は、reverse メソッドを使った部分です。
// もともと
entries.map(a => a.reverse())
// 自分だったら ver.
entries.map(([key, value]) => [value, key])
処理結果については全く変わりません。
map メソッドによってデータ([ 'morning', 'おはよう' ] )を 1 件ずつ取り出し、配列の 0 番目の要素である key と 1 番目の要素である value を入れ替えていることに変わりありません。
しかし、a => a.reverse() では「key と value を入れ替えている」という意図が伝わりづらいのではないか、と思い筆を取った次第です。
([key, value]) => [value, key] とすることで「key と value を取り出し、入れ替えた上で改めて配列として返却する」としたほうが、処理の意図が伝わりやすいのではないかと思いました。
③ Object.fromEntries
最後に Object.fromEntries でオブジェクトに変換し、完成です。
const reverseMap = Object.fromEntries(reverse)
console.log(reverseMap)
> {
> "おはよう": "morning",
> "こんにちは": "afternoon",
> "こんばんは": "evening"
> }
以上です。ご清聴ありがとうございました。
余談
記事を書いてて思いついた別解的なものも載せておきます。
Object.entries, reduce, Object.assign を使ってます。
Object.entries(greetingMessageMap).reduce((val, [key, value]) => Object.assign(val, {[value]: key}), {})
こちらは Object.assign の代わりにスプレッド構文を使ってます。
Object.entries(greetingMessageMap).reduce((val, [key, value]) => ({ ...val, [value]: key }), {})