0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

タプルがキーの Map

Last updated at Posted at 2025-07-10

fp-ts を使って実現できました。

環境構築

Bun を使いました。

$ bun init
$ bun install fp-ts

失敗例

大統領名の配列から、大統領ごとの在任回数を保持する Map を作ろうとしています。

term_count.ts
const recentPresidents: [string, string][] = [
  ["Donald", "Trump"],
  ["Joe", "Biden"],
  ["Donald", "Trump"],
];

const presidentTermCount = new Map<[string, string], number>();

for (const name of recentPresidents) {
  if (presidentTermCount.has(name)) {
    presidentTermCount.set(name, presidentTermCount.get(name)! + 1);
  } else {
    presidentTermCount.set(name, 1);
  }
}

console.log(presidentTermCount);

実行結果は以下のようになります。["Donald", "Trump"] の在任回数は 2 であるべきなのに、失敗しています。

$ bun run term_count.ts   
Map(3) {
  [ "Donald", "Trump" ]: 1,
  [ "Joe", "Biden" ]: 1,
  [ "Donald", "Trump" ]: 1,
}

成功例

Tuple は Array なので、string[] 用の Eq を使う Map を作ると、うまくいきました。

term_count_fp.ts
import * as A from "fp-ts/Array";
import * as N from "fp-ts/number";
import * as S from "fp-ts/string";
import * as Map from "fp-ts/Map";

const recentPresidents: [string, string][] = [
  ["Donald", "Trump"],
  ["Joe", "Biden"],
  ["Donald", "Trump"],
];

const presidentTermCount = Map.fromFoldable(
  A.getEq(S.Eq),
  N.SemigroupSum,
  A.Foldable
)(recentPresidents.map((name) => [name, 1]));

console.log(presidentTermCount);

実行結果は以下のようになります。

$ bun run term_count_fp.ts
Map(2) {
  [ "Donald", "Trump" ]: 2,
  [ "Joe", "Biden" ]: 1,
}

所感

実現はできましたが、難しすぎる気がします。生成 AI の助けも借りて何とか実装できましたが、どういう仕組みなのか、同僚が理解できるように説明する自信はありません。

この例だったら、キーを JSON とかスペース区切りの "Donald Trump" のような string にするのが実務的な解決策なのかな? 誰でも理解できるコードになりますよね。

もっと良い方法があったら教えていただきたいです。

0
0
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?