I have nested objects in array and i want to convert them into dot notation string with javascript.
This is my data sample data for converting process.
[
{
property: 'name',
children: [],
message: 'name should not be empty',
},
{
property: 'priceForm',
children: [
{
property: 'priceCurrency',
children: [],
message: 'priceCurrency should not be empty',
},
],
},
{
property: 'priceForm',
children: [
{
property: 'rolePrices',
children: [
{
property: '0',
children: [
{
property: 'markupType',
children: [],
message: 'markupType should not be empty',
},
],
},
],
},
],
},
]
Expected result is
{
'name': 'name should not be empty',
'priceForm.priceCurrency': 'priceCurrency should not be empty',
'priceForm.rolePrices.0.markupType': 'markupType should not be empty',
}
You could collect the path first and then build a property.
function getObject(array, path = '', target = {}) { array.forEach(({ property, children = [], message }) => { var temp = path + (path && '.') + property; if (children.length) { getObject(children, temp, target); return; } target[temp] = message; }); return target; } var array = [{ property: 'name', children: [], message: 'name should not be empty' }, { property: 'priceForm', children: [{ property: 'priceCurrency', children: [], message: 'priceCurrency should not be empty' }] }, { property: 'priceForm', children: [{ property: 'rolePrices', children: [{ property: '0', children: [{ property: 'markupType', children: [], message: 'markupType should not be empty' }] }] }] }], object = getObject(array); console.log(object);
You can use recursive function to format you want.
const data = [{ property: 'name', children: [], message: 'name should not be empty' }, { property: 'priceForm', children: [{ property: 'priceCurrency', children: [], message: 'priceCurrency should not be empty' }] }, { property: 'priceForm', children: [{ property: 'rolePrices', children: [{ property: '0', children: [{ property: 'markupType', children: [], message: 'markupType should not be empty' }] }] }] }]; let result = {}; function format(data, prefix) { prefix = prefix ? `${prefix}.` : '' let message = '' data.forEach(i => { prefix = `${prefix}${i.property}` message = i.message if (!i.children.length) { i.message && (result[prefix] = i.message) } else { let child_data = format(i.children, prefix) child_data['message'] && child_data['prefix'] && (result[`${prefix}.${child_data['prefix']}`] = child_data['message']) } prefix = '' }) return {prefix: prefix, message: message} } format(data) console.log(result)
Here you go! Array.reduce
and recursion is a good fit for this problem.
const foo = (data, prefix = "") => data.reduce( (acc, { property, message, children }) => ({ ...acc, ...(children.length ? foo(children, `${prefix}${property}.`) : { [`${prefix}${property}`]: message }) }), {} ); const data = [ { property: "name", children: [], message: "name should not be empty" }, { property: "priceForm", children: [ { property: "priceCurrency", children: [], message: "priceCurrency should not be empty" } ] }, { property: "priceForm", children: [ { property: "rolePrices", children: [ { property: "0", children: [ { property: "markupType", children: [], message: "markupType should not be empty" }, { property: "sibling!", children: [], message: "added a sibling to the input data" } ] } ] } ] } ]; console.log(foo(data));
Update cleaned up a bit. Basically a one liner now 🙌 Added a sibling to the input data too
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.