I'm in ES7/ES8, I want to know how to map an object's values, regardless of its keys (like Array.map).
I found this post here
But :
- I am forced to map also the whole object, not the just value
- I also want it to give a strongly typed type inference when assigning to a variable.
- (If possible in a functional coding style)
// === TO MODIFY ===
type AnyObjectKeys = string | number;
type AnyObject<
Values,
Keys extends AnyObjectKeys = AnyObjectKeys,
> = Record<Keys, Values>;
type MapperFunc<T> = (
value: [AnyObjectKeys, T],
index: number,
array: [AnyObjectKeys, T][],
) => unknown
/**
* map an object's values, like Array<T>.map
* but can also access its key with another signature
*/
const objMapper =
<AnyObjectValues>(object: AnyObject<AnyObjectValues>) =>
(func: MapperFunc<AnyObjectValues>) =>
Object.assign({}, ...Object.entries(object).map(func));
// === TO MODIFY ===
const getAverage = (arr: number[]) =>
arr.reduce((a, b) => a + b, 0) / arr.length
// BASE OBJECT
const curvesPointsByDynamicKeys = {
['a']: {
x: [3, 4, 1],
y: [6, 1, 4],
z: [3, 9, 0],
},
['b']: {
x: [2, 1, 0],
y: [9, 3, 3],
z: [4, 6, 0],
},
// ...
};
// EXPECTED USAGE 1 (with key access)
const curvesAveragePointsByDynamicKeys = objMapper(curvesPointsByDynamicKeys)
(
([key, { x, y, z }]) => {
return {
id: `curve-${key}-${x.length}-${y.length}-${z.length}`,
averageX: getAverage(x),
averageY: getAverage(y),
averageZ: getAverage(z),
}
}
);
// EXPECTED USAGE 2 (without key access)
const curvesAveragePointsByDynamicKeys2 = objMapper(curvesPointsByDynamicKeys)
(
({ x, y, z }) => {
return {
averageX: getAverage(x),
averageY: getAverage(y),
averageZ: getAverage(z),
}
}
);
// EXPECTED RESULT 1 :
// {
// ['a']: {
// id: '...',
// averageX: 2.6666666666666665,
// averageY: 3.6666666666666665,
// averageZ: 4,
// },
// ['b']: {
// id: '...',
// averageX: 1,
// averageY: 5,
// averageZ: 3.3333333333333335,
// },
// // ...
// }
console.log(curvesAveragePointsByDynamicKeys)
// EXPECTED RESULT 2 :
// {
// ['a']: {
// averageX: 2.6666666666666665,
// averageY: 3.6666666666666665,
// averageZ: 4,
// },
// ['b']: {
// averageX: 1,
// averageY: 5,
// averageZ: 3.3333333333333335,
// },
// // ...
// }
console.log(curvesAveragePointsByDynamicKeys2)
// NOT EXPECTED RESULT :
// {
// averageX: 1,
// averageY: 5,
// averageZ: 3.3333333333333335,
// }