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.
CodePudding user response:
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;
});