指定したキーの値を使って配列を連想配列に変換する関数をTypeScriptで作ったのでメモ。
とりあえず、変換後の連想配列のkeyにはstring
かnumber
を指定できるようにした。(numberの場合はstringに変換されちゃうけど)
/**
* 配列を指定したキーのMap Objectに変換する
*
* @param array
* @param {string} key 変換後の連想配列のキーに指定する値のキーを指定する。例 'id' / 'innerItem.name'
*/
export function arrayToMap<T>(array: T[], key: string = '') {
const obj: { [key: string]: T } = Object.create(null)
const re = /[\.\[\]]/
const keys = key.split(re).filter(str => str.length !== 0)
array.forEach((t, i) => {
if (typeof t === 'string' || typeof t === 'number') {
obj[t] = t
return
}
const _key = keys.reduce((acc, cur) => acc[cur], t as any)
if (typeof _key !== 'string' && typeof _key !== 'number') {
throw new Error(`array[${i}].${key} is ${typeof _key}. not string or number !!`)
}
obj[_key] = t
})
return obj
}
使い方は以下のような感じ、
sample.ts
const objArr = [
{
id: 11111,
name: 'aaa',
arrId: [
{id: 11111}
]
},
{
id: 2222,
name: 'bbb',
arrId: [
{id: 2222}
]
}
]
console.log(arrayToMap(objArr,'id'))
// => 'id'をキーにして連想配列を作る。結果は以下のような感じ
// {
// 2222: {
// id: 2222,
// name: "bbb",
// arrId: [
// {
// id: 2222
// }
// ]
// },
// 11111: {
// id: 11111,
// name: "aaa",
// arrId: [
// {
// id: 11111
// }
// ]
// }
// }
console.log(arrayToMap(objArr,'arrId[0].id'))
// => arrId[0].idをキーにして連想配列を作る、結果は上と同じ、
console.log(arrayToMap(objArr,'name'))
// => 'name'をキーにして連想配列を作る。結果は以下のような感じ
// {
// aaa: {
// id: 11111,
// name: "aaa",
// arrId: [
// {
// id: 11111
// }
// ]
// },
// bbb: {
// id: 2222,
// name: "bbb",
// arrId: [
// {
// id: 2222
// }
// ]
// }
// }
const strArr = [
'yamada', 'taro' , 'aaa'
]
console.log(arrayToMap(strArr))
// => arrayのメンバーが文字列の場合は、keyとvalueに同じ値が入る。
// {
// yamada: "yamada",
// taro: "taro",
// aaa: "aaa"
// }
const numArr = [
1111, 22222 , 33333
]
console.log(arrayToMap(numArr))
// => arrayのメンバーがnumberの場合もstringのときと同じ
// {
// 1111: 1111,
// 22222: 22222,
// 33333: 33333
// }
console.log(arrayToMap(objArr)) // => error. array[0]. is object. not string or number !!
console.log(arrayToMap(objArr, 'no_key')) // => error. array[0].no_key is undefined. not string or number !!
第2引数のキーの値に対してコンパイル時にチェックをかけられないのが微妙だけど、
返り値の型に対する推論はちゃんと効いてくれるのでまあいいかな・・・