質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
TypeScript

TypeScriptは、マイクロソフトによって開発された フリーでオープンソースのプログラミング言語です。 TypeScriptは、JavaScriptの構文の拡張であるので、既存の JavaScriptのコードにわずかな修正を加えれば動作します。

Q&A

解決済

2回答

932閲覧

typescript オブジェクトのキーでマップ処理

yochun02

総合スコア76

TypeScript

TypeScriptは、マイクロソフトによって開発された フリーでオープンソースのプログラミング言語です。 TypeScriptは、JavaScriptの構文の拡張であるので、既存の JavaScriptのコードにわずかな修正を加えれば動作します。

0グッド

0クリップ

投稿2020/10/07 10:45

編集2020/10/07 10:49

以下のコードで、オブジェクトの配列で、複数指定したキーを持つオブジェクトのみにマップ関数でリスト処理をしたいのですが場合分けがべた書きスマートじゃないです。(オブジェクトのキーが増えた場合などにリファクタしづらい。)keyを一気に扱う方法はありませんか?
他言語の
int x = 5
int y = 2
x in (1, 2, 3) → false
y in (1, 2, 3) → true
みたいな感じです

typescript

1type Obj = { 2 key: string, 3 name: string 4} 5const objs: Obj[] = [ 6 {key: "human", name: "私"}, 7 {key: "fish", name: "鮭"}, 8 {key: "mouse", name: "ハムスター"}, 9 {key: "flog", name: "アマガエル"} 10] 11const keys = objs.map(o => o.key) 12console.log( 13 keys.map( 14 key => { 15 if(key === "human" || key === "mouse") 16 return "哺乳類" 17 else if(key === "fish") 18 return "魚類" 19 else(key === "flog") 20 return "両生類" 21 } 22 ) 23 ) 24// 期待値 25["哺乳類", "魚類", "哺乳類", "両生類"] 26

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

こんにちは

"human" から "哺乳類" が得られるようなマップを作っておくのは、いかがでしょうか? 以下は、そのようなマップとして機能するオブジェクトkeyToLabelを作っておき、これを利用する例です。

以下のような内容のTSファイルを作っておきます。ファイルを仮に keyToLabel.ts としておきます。

keyToLabel.ts:

typescript

1const groups = { 2 哺乳類: ["human", "mouse"], 3 魚類: ["fish"], 4 両生類: ["flog"] 5} as const; 6 7 8type KV = [string, string]; 9type KVS = [string, readonly string[]]; 10 11const keyToLabel = Object.fromEntries( 12 Object.entries(groups).reduce( 13 (a: KV[], [label, keys]: KVS) => [ 14 ...a, 15 ...keys.map((k) => [k, label] as KV) 16 ], 17 [] 18 ) 19); 20 21export default keyToLabel;

今後、たとえば、哺乳類に "dog" を追加したり、"鳥類" を追加する場合は、groups に追加します。
上記のkeyToLabel.tsを作っておくと、ご質問の本題である配列を得るには、以下のようにすればよいです。

typescript

1import keyToLabel from "./keyToLabel";

typescript

1const keys = objs.map(({ key }: Obj) => keyToLabel[key]);

参考になれば幸いです。

備考

上記では、'哺乳類' => ["human", "mouse"] というエントリを含むオブジェクト groups をマスターデータとして、これの逆引きのマップであるkeyToLabel をプログラムで作りましたが、以下のように、はじめから keyToLabel をリテラルで書いてしまって、dog や 鳥類のcrow が追加されたときに、これに追加することもできます。

typescript

1const keyToLabel = { 2 human: '哺乳類', 3 mouse: '哺乳類', 4 fish: '魚類', 5 flog: '両生類' 6} as const; 7 8export default keyToLabel;

ただし、この場合は逆に、哺乳類 であるすべてのkeyを配列で得たいという場合は、なにがしかのコードを書く必要があります。

投稿2020/10/07 17:12

編集2020/10/07 18:36
jun68ykt

総合スコア9058

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

yochun02

2020/10/07 20:03 編集

詳しく教えていただきありがとうございます! 浅学で恐縮ですが、 map(({ key }: Obj) => keyToLabel[key])の部分は何をしているのかざっくりで良いので教えていただけませんか?(特に前半の形はあまり慣れてないので。。。map(x => {xの加工})の形しかみたことなかったです)
jun68ykt

2020/10/07 20:27

どういたしまして const keys = objs.map(({ key }: Obj) => keyToLabel[key]); についてですが、これを > map(x => {xの加工})の形 で書くと、ご質問にあるのと同様に const keys = objs.map((o: Obj) => keyToLabel[o.key]); となります。このときに、 map に与えている関数の引数 o を { key } としておき、関数本体のほうで、o.key ではなく、単に key を変数として使うのは、オブジェクトの分割代入の応用です。 https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment の中にある、「引数に指定されたオブジェクトの属性への参照」に、いくつかの事例が出ています。
jun68ykt

2020/10/07 20:49

補足 関数本体で、name も使うのであれば、 ({ key, name }: Obj) => ・・・ とします。
yochun02

2020/10/08 03:07 編集

なるほど!map内で分割代入もできるのですね。重ね重ね解答ありがとうございます。m(_ _)m
guest

0

配列を使って逆に考えてみました。ifの中を
にすればいいですかね。

typescript

1if(["human", "mouse"].some(arr => arr === key)) 2 return "哺乳類"

それでもって["human", "mouse"]のところをあらかじめ切り出しておけば。。

投稿2020/10/07 10:58

yochun02

総合スコア76

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問