map-anything
v3.0.1
Published
Array.map but for objects with good TypeScript support. A small and simple integration.
Downloads
4,050
Maintainers
Readme
Map anything 🗺
npm i map-anything
Array.map but for objects with good TypeScript support. A small and simple integration.
Motivation
I always want to do:
someObject.map((val) => someFunction)
But this doesn't exist for objects, you need to do this instead:
Object.entries(someObject).reduce((carry, [key, value], index, array) => {
carry[key] = someFunction(value, key, array)
return carry
}, {})
So I made a wrapper function for that. 😃
map-anything
has very good #TypeScript support as well.
Usage
Provided Functions:
mapObject
takes an object and maps over the values of each keymapObjectAsync
takes an object and maps a promise over the values of each key, after which you can just do a single awaitmapMap
takes a map and maps over the values of each key
Basic Usage
import { mapObject } from 'map-anything'
const pokemon = {
'001': { name: 'Bulbasaur', level: 10 },
'004': { name: 'Charmander', level: 8 },
'007': { name: 'Squirtle', level: 11 },
}
const levelUp = mapObject(pokemon, (pkmn) => {
return { ...pkmn, level: pkmn.level + 1 }
})
// results in:
levelUp ===
{
'001': { name: 'Bulbasaur', level: 11 },
'004': { name: 'Charmander', level: 9 },
'007': { name: 'Squirtle', level: 12 },
}
Access the propName in the map function
A function passed to Array.map
will get the value as first argument and an index as second. With mapObject
you will get the propName as second argument.
import { mapObject } from 'map-anything'
const pokemon = {
'001': { name: 'Bulbasaur', level: 10 },
'004': { name: 'Charmander', level: 8 },
'007': { name: 'Squirtle', level: 11 },
}
const addIds = mapObject(pokemon, (pkmn, propName) => {
const id = propName
return { ...pkmn, id }
})
// results in:
addIds ===
{
'001': { name: 'Bulbasaur', level: 10, id: '001' },
'004': { name: 'Charmander', level: 8, id: '004' },
'007': { name: 'Squirtle', level: 11, id: '007' },
}
Map Object Async
const pokemon = {
'001': { name: 'Bulbasaur', level: 10 },
'004': { name: 'Charmander', level: 8 },
'007': { name: 'Squirtle', level: 11 },
}
const result = await mapObjectAsync(pokemon, async (pkmn, propName) => {
const id = propName
const data = await fetchData(id) // hypothetical API call
return { ...pkmn, data }
})
// results in:
result ===
{
'001': { name: 'Bulbasaur', level: 10, data: '...' }, // some fetched data
'004': { name: 'Charmander', level: 8, data: '...' },
'007': { name: 'Squirtle', level: 11, data: '...' },
}
TypeScript
Without having to specify the return type in the reducer, I've set map-anything
up so it automatically detects that type for you!
Meet the family (more tiny utils with TS support)
- is-what 🙉
- is-where 🙈
- merge-anything 🥡
- check-anything 👁
- remove-anything ✂️
- getorset-anything 🐊
- map-anything 🗺
- filter-anything ⚔️
- copy-anything 🎭
- case-anything 🐫
- flatten-anything 🏏
- nestify-anything 🧅
Source code
The source code is rather simple, it's doing something like the snippet show here below. However, it's adding amazing typescript.
function mapObject (object, fn) {
return Object.entries(object)
.reduce((carry, [key, value], index, array) => {
carry[key] = fn(value, key, array)
return carry
}, {})
}