LoginSignup
0
0

More than 3 years have passed since last update.

指定したキーの値を使って配列を連想配列に変換する関数

Last updated at Posted at 2019-08-12

指定したキーの値を使って配列を連想配列に変換する関数をTypeScriptで作ったのでメモ。

とりあえず、変換後の連想配列のkeyにはstringnumberを指定できるようにした。(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引数のキーの値に対してコンパイル時にチェックをかけられないのが微妙だけど、
返り値の型に対する推論はちゃんと効いてくれるのでまあいいかな・・・

0
0
0

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