やりたいこと
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;
},
{}
);
前者の方がコード量的には少ないが、後者は全く副作用がない形で書かれている。
どっちをとるのがベストか...