Give an arbitrary array of objects and an array of paths as strings in "dot notation" format is there a way to project to a new object?
For example given an array people and a list of paths (dot notation):
const people = [
{
firstName: 'John',
lastName: 'Doe',
address: {
city: 'New York',
country: 'US'
}
},
{
firstName: 'Sally',
lastName: 'Jane',
address: {
city: 'Londaon',
country: 'UK'
}
}
] as Person[]
const paths = ['firstName','address.country'];
Is there a way using Array.map(p => ???)
to dynamically project with just the provided paths? The result for the above would end up being:
[
{
firstName: 'John',
address: {
country: 'US'
}
},
{
firstName: 'Sally',
address: {
country: 'UK'
}
}
]
My end goal is to take an array of objects and serialize using JSON.stringify(people)
using the selected paths.
You could recursively follow the paths and then always pass along the object of at the last path. E.g:
function followPath(obj: any, pathParts: string[]): any {
const result: { [k: string]: any } = {};
const firstPath = pathParts.shift();
if (firstPath === undefined) {
return {};
}
if (pathParts.length > 0) {
result[firstPath] = followPath(obj[firstPath], pathParts);
} else {
result[firstPath] = obj[firstPath];
}
return result;
}
const paths = ['firstName', 'address.country'];
const newArray = oldArray.map((v) => {
const newObject = {};
for (const path of paths) {
const parts = path.split('.');
const firstPath = parts.shift();
if (firstPath === undefined) {
continue;
}
newObject[firstPath] = parts.length > 0
? followPath(v[firstPath], parts)
: v[firstPath];
}
return newObject;
});