Reputation: 9095
I have a below data structure. From it I need to extract the columns which is an array and I need to build an object with key and actual label name.
Is there any better way to achieve this?
let data = {
"section1": {
"forms": [
{
"fields": [
{
"columnName": "test1",
"label": [
{
"actualLabel": "Test 1"
}
]
},
{
"columnName": "test2",
"label": [
{
"actualLabel": "Test 2"
}
]
},
{
"columnName": "test0",
"label": [
{
"actualLabel": "Test 0"
}
]
}
]
},
{
"fields": [
{
"columnName": "test6",
"label": [
{
"actualLabel": "Test 6"
}
]
},
{
"columnName": "test3",
"label": [
{
"actualLabel": "Test 3"
}
]
},
{
"columnName": "test10",
"label": [
{
"actualLabel": "Test 10"
}
]
}
]
},
{
"fields": [
{
"columnName": "test15",
"label": [
{
"actualLabel": "Test 15"
}
]
},
{
"columnName": "test",
"label": [
{
"actualLabel": "Test 6"
}
]
},
{
"columnName": "test7",
"label": [
{
"actualLabel": "Test 7"
}
]
}
]
}
]
},
"section2": {
"forms": [
{
"fields": [
{
"columnName": "test1",
"label": [
{
"actualLabel": "Test 1"
}
]
},
{
"columnName": "test2",
"label": [
{
"actualLabel": "Test 2"
}
]
},
{
"columnName": "test0",
"label": [
{
"actualLabel": "Test 0"
}
]
}
]
},
{
"fields": [
{
"columnName": "test3",
"label": [
{
"actualLabel": "Test 3"
}
]
},
{
"columnName": "test4",
"label": [
{
"actualLabel": "Test 4"
}
]
},
{
"columnName": "test10",
"label": [
{
"actualLabel": "Test 10"
}
]
}
]
},
{
"fields": [
{
"columnName": "test5",
"label": [
{
"actualLabel": "Test 5"
}
]
},
{
"columnName": "test6",
"label": [
{
"actualLabel": "Test 6"
}
]
},
{
"columnName": "test7",
"label": [
{
"actualLabel": "Test 7"
}
]
}
]
}
]
},
"section3": {
"forms": [
{
"fields": [
{
"columnName": "test1",
"label": [
{
"actualLabel": "Test 1"
}
]
},
{
"columnName": "test2",
"label": [
{
"actualLabel": "Test 2"
}
]
},
{
"columnName": "test0",
"label": [
{
"actualLabel": "Test 0"
}
]
}
]
},
{
"fields": [
{
"columnName": "test3",
"label": [
{
"actualLabel": "Test 3"
}
]
},
{
"columnName": "test 4",
"label": [
{
"actualLabel": "Test 4"
}
]
},
{
"columnName": "test10",
"label": [
{
"actualLabel": "Test 10"
}
]
}
]
},
{
"fields": [
{
"columnName": "test15",
"label": [
{
"actualLabel": "Test 15"
}
]
},
{
"columnName": "test6",
"label": [
{
"actualLabel": "Test 6"
}
]
},
{
"columnName": "test7",
"label": [
{
"actualLabel": "Test 7"
}
]
}
]
}
]
}
}
let extractColumns = ['test1', 'test2', 'test7', 'test15']
let result = Object.entries(data).reduce(
(initial, [key, { forms }]) => {
forms.forEach(({ fields }) => {
fields.forEach(
({
columnName,
label: {
0: { actualLabel },
},
}) => {
if (extractColumns.indexOf(columnName) > -1) {
initial[columnName] = {
actualLabel,
};
}
},
);
});
return initial;
},
{},
);
console.log(result)
Upvotes: 1
Views: 85
Reputation: 2099
I propose more general solution. Inspired babel.
const data = {
"section1": {
"forms": [{
"fields": [{
"columnName": "test1",
"label": [{
"actualLabel": "Test 1"
}]
},
{
"columnName": "test2",
"label": [{
"actualLabel": "Test 2"
}]
},
{
"columnName": "test0",
"label": [{
"actualLabel": "Test 0"
}]
}
]
},
{
"fields": [{
"columnName": "test6",
"label": [{
"actualLabel": "Test 6"
}]
},
{
"columnName": "test3",
"label": [{
"actualLabel": "Test 3"
}]
},
{
"columnName": "test10",
"label": [{
"actualLabel": "Test 10"
}]
}
]
},
{
"fields": [{
"columnName": "test15",
"label": [{
"actualLabel": "Test 15"
}]
},
{
"columnName": "test",
"label": [{
"actualLabel": "Test 6"
}]
},
{
"columnName": "test7",
"label": [{
"actualLabel": "Test 7"
}]
}
]
}
]
},
"section2": {
"forms": [{
"fields": [{
"columnName": "test1",
"label": [{
"actualLabel": "Test 1"
}]
},
{
"columnName": "test2",
"label": [{
"actualLabel": "Test 2"
}]
},
{
"columnName": "test0",
"label": [{
"actualLabel": "Test 0"
}]
}
]
},
{
"fields": [{
"columnName": "test3",
"label": [{
"actualLabel": "Test 3"
}]
},
{
"columnName": "test4",
"label": [{
"actualLabel": "Test 4"
}]
},
{
"columnName": "test10",
"label": [{
"actualLabel": "Test 10"
}]
}
]
},
{
"fields": [{
"columnName": "test5",
"label": [{
"actualLabel": "Test 5"
}]
},
{
"columnName": "test6",
"label": [{
"actualLabel": "Test 6"
}]
},
{
"columnName": "test7",
"label": [{
"actualLabel": "Test 7"
}]
}
]
}
]
},
"section3": {
"forms": [{
"fields": [{
"columnName": "test1",
"label": [{
"actualLabel": "Test 1"
}]
},
{
"columnName": "test2",
"label": [{
"actualLabel": "Test 2"
}]
},
{
"columnName": "test0",
"label": [{
"actualLabel": "Test 0"
}]
}
]
},
{
"fields": [{
"columnName": "test3",
"label": [{
"actualLabel": "Test 3"
}]
},
{
"columnName": "test 4",
"label": [{
"actualLabel": "Test 4"
}]
},
{
"columnName": "test10",
"label": [{
"actualLabel": "Test 10"
}]
}
]
},
{
"fields": [{
"columnName": "test15",
"label": [{
"actualLabel": "Test 15"
}]
},
{
"columnName": "test6",
"label": [{
"actualLabel": "Test 6"
}]
},
{
"columnName": "test7",
"label": [{
"actualLabel": "Test 7"
}]
}
]
}
]
}
}
function walking(o, callback, result) {
if (Array.isArray(o)) {
callback('array', o, result);
for (let i = 0; i < o.length; i++) {
walking(o[i], callback, result);
}
} else if (typeof o === 'object') {
callback('object', o, result);
for (let name in o) {
walking(o[name], callback, result);
}
} else {
callback('primitive', o, result);
}
return result;
}
function handler(type, value, result) {
const extractColumns = ['test1', 'test2', 'test7', 'test15'];
if (type == 'object') {
if ('columnName' in value && 'label' in value) {
if (extractColumns.indexOf(value.columnName) !== -1) {
result[value.columnName] = value.label[0];
}
}
}
}
console.log(walking(data, handler, Object.create(null)));
Upvotes: 0
Reputation: 35202
Another option is to get an array of fields using flatMap
and then filter
them to get the output. You could create a Set
instead of an array of columns since Set#has
is much faster than includes
let data={"section1":{"forms":[{"fields":[{"columnName":"test1","label":[{"actualLabel":"Test 1"}]},{"columnName":"test2","label":[{"actualLabel":"Test 2"}]},{"columnName":"test0","label":[{"actualLabel":"Test 0"}]}]},{"fields":[{"columnName":"test6","label":[{"actualLabel":"Test 6"}]},{"columnName":"test3","label":[{"actualLabel":"Test 3"}]},{"columnName":"test10","label":[{"actualLabel":"Test 10"}]}]},{"fields":[{"columnName":"test15","label":[{"actualLabel":"Test 15"}]},{"columnName":"test","label":[{"actualLabel":"Test 6"}]},{"columnName":"test7","label":[{"actualLabel":"Test 7"}]}]}]},"section2":{"forms":[{"fields":[{"columnName":"test1","label":[{"actualLabel":"Test 1"}]},{"columnName":"test2","label":[{"actualLabel":"Test 2"}]},{"columnName":"test0","label":[{"actualLabel":"Test 0"}]}]},{"fields":[{"columnName":"test3","label":[{"actualLabel":"Test 3"}]},{"columnName":"test4","label":[{"actualLabel":"Test 4"}]},{"columnName":"test10","label":[{"actualLabel":"Test 10"}]}]},{"fields":[{"columnName":"test5","label":[{"actualLabel":"Test 5"}]},{"columnName":"test6","label":[{"actualLabel":"Test 6"}]},{"columnName":"test7","label":[{"actualLabel":"Test 7"}]}]}]},"section3":{"forms":[{"fields":[{"columnName":"test1","label":[{"actualLabel":"Test 1"}]},{"columnName":"test2","label":[{"actualLabel":"Test 2"}]},{"columnName":"test0","label":[{"actualLabel":"Test 0"}]}]},{"fields":[{"columnName":"test3","label":[{"actualLabel":"Test 3"}]},{"columnName":"test 4","label":[{"actualLabel":"Test 4"}]},{"columnName":"test10","label":[{"actualLabel":"Test 10"}]}]},{"fields":[{"columnName":"test15","label":[{"actualLabel":"Test 15"}]},{"columnName":"test6","label":[{"actualLabel":"Test 6"}]},{"columnName":"test7","label":[{"actualLabel":"Test 7"}]}]}]}}
let extractColumns = new Set(['test1', 'test2', 'test7', 'test15'])
const output = Object.values(data).reduce((acc, { forms }) => {
forms.flatMap(a => a.fields)
.filter(f => extractColumns.has(f.columnName))
.forEach(({ columnName, label: [o] }) => acc[columnName] = o)
return acc;
}, {})
console.log(output)
(I haven't checked if it's faster than what you already have)
Upvotes: 1
Reputation: 44087
You can simplify and compact the code like so - using Object.values
, includes
, ternary operators, and simplified array destructuring.
let data={"section1":{"forms":[{"fields":[{"columnName":"test1","label":[{"actualLabel":"Test 1"}]},{"columnName":"test2","label":[{"actualLabel":"Test 2"}]},{"columnName":"test0","label":[{"actualLabel":"Test 0"}]}]},{"fields":[{"columnName":"test6","label":[{"actualLabel":"Test 6"}]},{"columnName":"test3","label":[{"actualLabel":"Test 3"}]},{"columnName":"test10","label":[{"actualLabel":"Test 10"}]}]},{"fields":[{"columnName":"test15","label":[{"actualLabel":"Test 15"}]},{"columnName":"test","label":[{"actualLabel":"Test 6"}]},{"columnName":"test7","label":[{"actualLabel":"Test 7"}]}]}]},"section2":{"forms":[{"fields":[{"columnName":"test1","label":[{"actualLabel":"Test 1"}]},{"columnName":"test2","label":[{"actualLabel":"Test 2"}]},{"columnName":"test0","label":[{"actualLabel":"Test 0"}]}]},{"fields":[{"columnName":"test3","label":[{"actualLabel":"Test 3"}]},{"columnName":"test4","label":[{"actualLabel":"Test 4"}]},{"columnName":"test10","label":[{"actualLabel":"Test 10"}]}]},{"fields":[{"columnName":"test5","label":[{"actualLabel":"Test 5"}]},{"columnName":"test6","label":[{"actualLabel":"Test 6"}]},{"columnName":"test7","label":[{"actualLabel":"Test 7"}]}]}]},"section3":{"forms":[{"fields":[{"columnName":"test1","label":[{"actualLabel":"Test 1"}]},{"columnName":"test2","label":[{"actualLabel":"Test 2"}]},{"columnName":"test0","label":[{"actualLabel":"Test 0"}]}]},{"fields":[{"columnName":"test3","label":[{"actualLabel":"Test 3"}]},{"columnName":"test 4","label":[{"actualLabel":"Test 4"}]},{"columnName":"test10","label":[{"actualLabel":"Test 10"}]}]},{"fields":[{"columnName":"test15","label":[{"actualLabel":"Test 15"}]},{"columnName":"test6","label":[{"actualLabel":"Test 6"}]},{"columnName":"test7","label":[{"actualLabel":"Test 7"}]}]}]}};
let extractColumns = ['test1', 'test2', 'test7', 'test15'];
const result = Object.values(data).reduce((acc, { forms }) => {
forms.forEach(({ fields }) => fields.forEach(({ columnName, label: [{ actualLabel }]}) => extractColumns.includes(columnName) ? acc[columnName] = { actualLabel } : null));
return acc;
}, {});
console.log(result)
Upvotes: 1