LoginSignup
0
0

More than 3 years have passed since last update.

keyとvalueをkeyとしてもつオブジェクトの配列からオブジェクトを生成する

Posted at

やりたいこと

keyとvalueをkeyとしてもつオブジェクトの配列 (idNamePairs)からidがkeyに対応し、nameがvalueに対応したオブジェクトを生成する関数convertToObjを書きたい。

const idNamePairs = [
  { id: 3, name: "john" },
  { id: 2, name: "mary" },
  { id: 5, name: "max" }
];
const mappingTable = convertToObj(idNamePairs);
console.log(mappingTable);
// 実行結果は { '2': 'mary', '3': 'john', '5': 'max' }

方法1: for-loopで空のオブジェクトに一個ずつ入れていく方法

const idNamePairs: { id: number; name: string }[] = [
  { id: 3, name: "john" },
  { id: 2, name: "mary" },
  { id: 5, name: "max" }
];
const mappingTable: { [key: string]: string } = {};
for (let pair of idNamePairs) {
  mappingTable[pair.id] = pair.name;
}

"The art of readable code"にも書かれていたと思うが、変数を定義する (上でのmappingTable)ということは脳内のメモリを消費することになる。しかも、一度constで定義した変数をいじっているのでなんか気持ち悪い。

方法2: Array.reduceを使う

変数を定義し変更を加えていくスタイルをやめるには、Array.reduceを使う。
reduceの初期値として空のオブジェクトを指定し、callbackで各要素についてkey-valueを指定していく。

const idNamePairs: { id: number; name: string }[] = [
  { id: 3, name: "john" },
  { id: 2, name: "mary" },
  { id: 5, name: "max" }
];
const mappingTable = idNamePairs.reduce<{ [key: string]: string }>(
  (table, { id, name }) => {
    table[id] = name;
    return table;
  },
  {}
);

前者の方がコード量的には少ないが、後者は全く副作用がない形で書かれている。
どっちをとるのがベストか...

0
0
1

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