I am trying to map an array with key like below
const data = [{
"_id": "5f0ffb96d67d70c1a3b143e7",
"name": "USER",
"type": "CUSTOM",
"origin": "USER",
"conditions": [{
"_id": "5f0ffb96d67d70c1a3b143e8",
"field": "status",
"value": "Nomita",
"operator": "equal"
}, {
"_id": "5f0ffb96d67d70c1a3b143e9",
"field": "current_status",
"value": "ACTIVE",
"operator": "equal"
}, {
"_id": "5f0ffb96d67d70c1a3b143ea",
"field": "user_group_uuid",
"value": "d12s0a7c-11ac-7abf-bl03-f0b70e26f8f2",
"operator": "equal"
}, {
"_id": "5f0ffb96d67d70c1a3b143eb",
"field": "user_group_uuid",
"value": "20348751-dcaa-4227-a0ff-912b27180aee",
"operator": "equal"
}]
}]
The above is the input.
const filters_data = { ...data[0] }
const filters_mapping = (array, keyField) =>
array.reduce((obj, item) => {
obj[item[keyField]] = item
return obj
}, {})
const filter_items = filters_mapping(filters_data.conditions,'field');
From this code I am getting
{ user_status:
{ _id: 5f0ffb96d67d70c1a3b143e8,
field: 'status',
value: 'Nomita',
operator: 'equal' },
current_status:
{ _id: 5f0ffb96d67d70c1a3b143e9,
field: 'current_status',
value: 'ACTIVE',
operator: 'equal' },
user_group_uuid:
{ _id: 5f0ffb96d67d70c1a3b143eb,
field: 'user_group_uuid',
value: 'd12s0a7c-11ac-7abf-bl03-f0b70e26f8f2',
operator: 'equal' } }
But I actually want something like this, that maps the value in array when the field is similar.
{ user_status:
{ _id: 5f0ffb96d67d70c1a3b143e8,
field: 'status',
value: 'Nomita',
operator: 'equal' },
current_status:
{ _id: 5f0ffb96d67d70c1a3b143e9,
field: 'current_status',
value: 'ACTIVE',
operator: 'equal' },
user_group_uuid:
{ _id: 5f0ffb96d67d70c1a3b143eb,
field: 'user_group_uuid',
value: ['d12s0a7c-11ac-7abf-bl03-f0b70e26f8f2','20348751-dcaa-4227-a0ff-912b27180aee'],
operator: 'equal' } }
this should happen only when there's multiple fields are available or else, it would return normal string only.
Ciao, I'm using your code but before reduce I combine value with same field value.
Here working example:
const data = [{
"_id": "5f0ffb96d67d70c1a3b143e7",
"name": "USER",
"type": "CUSTOM",
"origin": "USER",
"conditions": [{
"_id": "5f0ffb96d67d70c1a3b143e8",
"field": "status",
"value": "Nomita",
"operator": "equal"
}, {
"_id": "5f0ffb96d67d70c1a3b143e9",
"field": "current_status",
"value": "ACTIVE",
"operator": "equal"
}, {
"_id": "5f0ffb96d67d70c1a3b143ea",
"field": "user_group_uuid",
"value": "d12s0a7c-11ac-7abf-bl03-f0b70e26f8f2",
"operator": "equal"
}, {
"_id": "5f0ffb96d67d70c1a3b143eb",
"field": "user_group_uuid",
"value": "20348751-dcaa-4227-a0ff-912b27180aee",
"operator": "equal"
}]
}]
const conditions_combined = _.uniqWith(data[0].conditions, function(a, b) {
if (a.field === b.field) {
b.value += ', ' + a.value;
b.value = b.value.split(",");
return true;
}
});
data[0].conditions = conditions_combined;
const filters_data = { ...data[0] };
const filters_mapping = (array, keyField) =>
array.reduce((obj, item) => {
obj[item[keyField]] = item
return obj
}, {})
const filter_items = filters_mapping(filters_data.conditions,'field');
console.log(filter_items);
<script src="https://cdn.jsdelivr.net/npm/lodash#4.17.10/lodash.min.js"></script>
Explanation: I'm using _.uniqWith from lodash to combine value with same field value.
Here is one possible soluce.
Your code doesn't handle the case where the key already exists.
const data = [{
"_id": "5f0ffb96d67d70c1a3b143e7",
"name": "USER",
"type": "CUSTOM",
"origin": "USER",
"conditions": [{
"_id": "5f0ffb96d67d70c1a3b143e8",
"field": "status",
"value": "Nomita",
"operator": "equal"
}, {
"_id": "5f0ffb96d67d70c1a3b143e9",
"field": "current_status",
"value": "ACTIVE",
"operator": "equal"
}, {
"_id": "5f0ffb96d67d70c1a3b143ea",
"field": "user_group_uuid",
"value": "d12s0a7c-11ac-7abf-bl03-f0b70e26f8f2",
"operator": "equal"
}, {
"_id": "5f0ffb96d67d70c1a3b143eb",
"field": "user_group_uuid",
"value": "20348751-dcaa-4227-a0ff-912b27180aee",
"operator": "equal"
}]
}];
const mutatedData = data[0].conditions.reduce((tmp, {
_id,
field,
value,
operator,
}) => {
// Handle the case where the field already exists
if (tmp[field]) {
tmp[field].value = [
...(tmp[field].value instanceof Array ?
tmp[field].value : [tmp[field].value]),
value,
];
return tmp;
}
// Handle the case where the field doesn't exist yet
tmp[field] = {
_id,
field,
value,
operator,
};
return tmp;
}, {});
console.log(mutatedData);
Condensed version
const data = [{
"_id": "5f0ffb96d67d70c1a3b143e7",
"name": "USER",
"type": "CUSTOM",
"origin": "USER",
"conditions": [{
"_id": "5f0ffb96d67d70c1a3b143e8",
"field": "status",
"value": "Nomita",
"operator": "equal"
}, {
"_id": "5f0ffb96d67d70c1a3b143e9",
"field": "current_status",
"value": "ACTIVE",
"operator": "equal"
}, {
"_id": "5f0ffb96d67d70c1a3b143ea",
"field": "user_group_uuid",
"value": "d12s0a7c-11ac-7abf-bl03-f0b70e26f8f2",
"operator": "equal"
}, {
"_id": "5f0ffb96d67d70c1a3b143eb",
"field": "user_group_uuid",
"value": "20348751-dcaa-4227-a0ff-912b27180aee",
"operator": "equal"
}]
}];
const mutatedData = data[0].conditions.reduce((tmp, {
_id,
field,
value,
operator,
}) => (tmp[field] = tmp[field] ? ((tmp[field].value = [
...(tmp[field].value instanceof Array ?
tmp[field].value : [tmp[field].value]),
value,
]) && tmp[field]) : {
_id,
field,
value,
operator,
}) && tmp, {});
console.log(mutatedData);
I was trying to access key, values from the below array
I am trying to access keys inside the fields object and value from the model inside keys object
formFields = [
{
"title": "Criteria Details",
"columns": 2,
"fields": {
"criteriaName": {
"type": "text",
"label": "Criteria Name",
"id": 'criteriaName',
"model": "CRITERIA 1",
"required": true,
"show": true,
"rules": [
v => !!v || 'Criteria Name is required',
]
},
"criteriaType": {
"type": "select",
"label": "Criteria type",
"id": "criteriaType",
"options": ['Dependent', 'Independent', 'Static'],
"model": "Dependent",
"required": true,
"rules": [
v => !!v || 'Criteria Type is required',
],
"show": true,
},
"table": {
"type": "select",
"label": "Table",
"id": "table",
"options": ["Table1"],
"model": "Table1",
"required": true,
"rules": [
v => !!v || 'Table is required',
],
"show": true,
},
"column": {
"type": "select",
"label": "Column",
"id": "column",
"options": ["Column1"],
"model": "Column1",
"required": true,
"rules": [
v => !!v || 'Column is required',
],
"show": true,
},
"joinType": {
"type": "select",
"label": "Join Type",
"id": "joinType",
"options": ["AND", "OR"],
"model": "OR",
"required": true,
"rules": [
v => !!v || 'Join Type is required',
],
"show": true,
},
"operator": {
"type": "select",
"label": "Operator",
"id": "operator",
"options": ["<", "<=", "<>", "=", ">=", ">", "EXISTS", "IN", "IS NOT NULL", "NULL", "LIKE", "NOT EXISTS", "NOT IN", "NOT LIKE"],
"model": ">=",
"required": true,
"rules": [
v => !!v || 'Operator is required',
],
"show": true,
},
"valueType": {
"type": "select",
"label": "Value Type",
"id": "valueType",
"options": ["Dependent SQL", "SQL", "VALUE"],
"model": "SQL",
"required": true,
"rules": [
v => !!v || 'Value Type is required',
],
"show": true,
},
"dataType": {
"type": "select",
"label": "Data Type",
"id": "dataType",
"options": ["DATE", "NUMBER", "STRING"],
"model": "NUMBER",
"required": true,
"rules": [
v => !!v || 'Data Type is required',
],
"show": true,
},
"format": {
"type": "text",
"label": "Format",
"id": "format",
"model": "Config",
"required": false,
"show": true,
},
"parameterMandatory": {
"type": "select",
"label": "Parameter Mandatory",
"id": "parameterMandatory",
"options": ["NO", "YES"],
"model": "YES",
"required": true,
"rules": [
v => !!v || 'Parameter Mandatory is required',
],
"show": true,
},
"link": {
"type": "select",
"label": "Link",
"id": "link",
"options": ["KB"],
"model": "KB",
"required": false,
"show": true,
},
"sequence": {
'type': "text",
"label": "Sequence",
"id": "sequence",
"model": "SEQ1",
"required": true,
"rules": [
v => !!v || 'Sequence is required',
],
"show": true,
},
"value": {
"type": "description_notes",
"label": "Value",
"id": "value",
"model": "VAL",
"required": true,
"rules": [
v => !!v || 'Value is required',
],
"show": true,
}
}
},
{
'title': "Notes",
"columns": 1,
"fields": {
"description": {
"type": "description_notes",
"label": "Description",
"id": "description",
"required": false,
"model": 'abcde',
"show": true,
}
}
}
]
****The Output i was trying is like this.****
How to access the keys and values from the above array like this.
Which method we need to use
criteriaDetails: [
{"criteriaName": "CRITERIA 1"},
{"criteriaType": "Dependent"},
{"table": "Table1"},
{"column": "Column1"},
{"joinType": "OR"},
{"operator": ">="},
{"valueType": "SQL"},
{"dataType": "NUMBER"},
{"format": "Config"},
{"parameterMandatory": "YES"},
{"link": "KB"},
{"sequence": "SEQ1"},
{"value": "VAL"},
{"description": "abcde"}
]
I tried below code
const field = this.formFields.map(field => {
return Object.entries(field.fields)
})
console.log(field)
how can I achieve this?
How to solve this. Please help
Thanks..
It looks like all you need to do is iterate over each fields object, and extract the key and the model property from each:
const formFields=[{"title":"Criteria Details","columns":2,"fields":{"criteriaName":{"type":"text","label":"Criteria Name","id":'criteriaName',"model":"CRITERIA 1","required":!0,"show":!0,"rules":[v=>!!v||'Criteria Name is required',]},"criteriaType":{"type":"select","label":"Criteria type","id":"criteriaType","options":['Dependent','Independent','Static'],"model":"Dependent","required":!0,"rules":[v=>!!v||'Criteria Type is required',],"show":!0,},"table":{"type":"select","label":"Table","id":"table","options":["Table1"],"model":"Table1","required":!0,"rules":[v=>!!v||'Table is required',],"show":!0,},"column":{"type":"select","label":"Column","id":"column","options":["Column1"],"model":"Column1","required":!0,"rules":[v=>!!v||'Column is required',],"show":!0,},"joinType":{"type":"select","label":"Join Type","id":"joinType","options":["AND","OR"],"model":"OR","required":!0,"rules":[v=>!!v||'Join Type is required',],"show":!0,},"operator":{"type":"select","label":"Operator","id":"operator","options":["<","<=","<>","=",">=",">","EXISTS","IN","IS NOT NULL","NULL","LIKE","NOT EXISTS","NOT IN","NOT LIKE"],"model":">=","required":!0,"rules":[v=>!!v||'Operator is required',],"show":!0,},"valueType":{"type":"select","label":"Value Type","id":"valueType","options":["Dependent SQL","SQL","VALUE"],"model":"SQL","required":!0,"rules":[v=>!!v||'Value Type is required',],"show":!0,},"dataType":{"type":"select","label":"Data Type","id":"dataType","options":["DATE","NUMBER","STRING"],"model":"NUMBER","required":!0,"rules":[v=>!!v||'Data Type is required',],"show":!0,},"format":{"type":"text","label":"Format","id":"format","model":"Config","required":!1,"show":!0,},"parameterMandatory":{"type":"select","label":"Parameter Mandatory","id":"parameterMandatory","options":["NO","YES"],"model":"YES","required":!0,"rules":[v=>!!v||'Parameter Mandatory is required',],"show":!0,},"link":{"type":"select","label":"Link","id":"link","options":["KB"],"model":"KB","required":!1,"show":!0,},"sequence":{'type':"text","label":"Sequence","id":"sequence","model":"SEQ1","required":!0,"rules":[v=>!!v||'Sequence is required',],"show":!0,},"value":{"type":"description_notes","label":"Value","id":"value","model":"VAL","required":!0,"rules":[v=>!!v||'Value is required',],"show":!0,}}},{'title':"Notes","columns":1,"fields":{"description":{"type":"description_notes","label":"Description","id":"description","required":!1,"model":'abcde',"show":!0,}}}]
const output = [];
formFields.forEach(({ fields }) => {
Object.entries(fields).forEach(([key, { model }]) => {
output.push({ [key]: model });
});
});
console.log(output);
The ({ fields}) is destructuring the object you pass to the callback. It would be equivalent to
formFields.forEach((obj) => {
Object.entries(obj.fields)
Object.entries will return an array with two values, the first is the current key and the second is the object associated with the key. That's why you can destructure again with (([key, { model }]).
As a reference you could rewrite the whole thing as
formFields.forEach((curObj) => {
Object.entries(curObj.fields).forEach(([key, fieldValues]) => {
output[key] = fieldValues.model;
});
});
const formFields = [{"title":"Criteria Details","columns":2,"fields":{"criteriaName":{"type":"text","label":"Criteria Name","id":'criteriaName',"model":"CRITERIA 1","required":!0,"show":!0,"rules":[v=>!!v||'Criteria Name is required',]},"criteriaType":{"type":"select","label":"Criteria type","id":"criteriaType","options":['Dependent','Independent','Static'],"model":"Dependent","required":!0,"rules":[v=>!!v||'Criteria Type is required',],"show":!0,},"table":{"type":"select","label":"Table","id":"table","options":["Table1"],"model":"Table1","required":!0,"rules":[v=>!!v||'Table is required',],"show":!0,},"column":{"type":"select","label":"Column","id":"column","options":["Column1"],"model":"Column1","required":!0,"rules":[v=>!!v||'Column is required',],"show":!0,},"joinType":{"type":"select","label":"Join Type","id":"joinType","options":["AND","OR"],"model":"OR","required":!0,"rules":[v=>!!v||'Join Type is required',],"show":!0,},"operator":{"type":"select","label":"Operator","id":"operator","options":["<","<=","<>","=",">=",">","EXISTS","IN","IS NOT NULL","NULL","LIKE","NOT EXISTS","NOT IN","NOT LIKE"],"model":">=","required":!0,"rules":[v=>!!v||'Operator is required',],"show":!0,},"valueType":{"type":"select","label":"Value Type","id":"valueType","options":["Dependent SQL","SQL","VALUE"],"model":"SQL","required":!0,"rules":[v=>!!v||'Value Type is required',],"show":!0,},"dataType":{"type":"select","label":"Data Type","id":"dataType","options":["DATE","NUMBER","STRING"],"model":"NUMBER","required":!0,"rules":[v=>!!v||'Data Type is required',],"show":!0,},"format":{"type":"text","label":"Format","id":"format","model":"Config","required":!1,"show":!0,},"parameterMandatory":{"type":"select","label":"Parameter Mandatory","id":"parameterMandatory","options":["NO","YES"],"model":"YES","required":!0,"rules":[v=>!!v||'Parameter Mandatory is required',],"show":!0,},"link":{"type":"select","label":"Link","id":"link","options":["KB"],"model":"KB","required":!1,"show":!0,},"sequence":{'type':"text","label":"Sequence","id":"sequence","model":"SEQ1","required":!0,"rules":[v=>!!v||'Sequence is required',],"show":!0,},"value":{"type":"description_notes","label":"Value","id":"value","model":"VAL","required":!0,"rules":[v=>!!v||'Value is required',],"show":!0,}}},{'title':"Notes","columns":1,"fields":{"description":{"type":"description_notes","label":"Description","id":"description","required":!1,"model":'abcde',"show":!0,}}}]
let result = []
formFields.forEach(item => {
const entries = Object.entries(item.fields)
entries.forEach(([key, { model }]) => {
result.push({
[key]: model
})
})
})
console.log(result)
There are many ways to do this.
You can use the Array.prototype.reduce() method to reduce the array to a single value, and use the Object.entries static method to extract the key and value
const formFields=[{"title":"Criteria Details","columns":2,"fields":{"criteriaName":{"type":"text","label":"Criteria Name","id":'criteriaName',"model":"CRITERIA 1","required":!0,"show":!0,"rules":[v=>!!v||'Criteria Name is required',]},"criteriaType":{"type":"select","label":"Criteria type","id":"criteriaType","options":['Dependent','Independent','Static'],"model":"Dependent","required":!0,"rules":[v=>!!v||'Criteria Type is required',],"show":!0,},"table":{"type":"select","label":"Table","id":"table","options":["Table1"],"model":"Table1","required":!0,"rules":[v=>!!v||'Table is required',],"show":!0,},"column":{"type":"select","label":"Column","id":"column","options":["Column1"],"model":"Column1","required":!0,"rules":[v=>!!v||'Column is required',],"show":!0,},"joinType":{"type":"select","label":"Join Type","id":"joinType","options":["AND","OR"],"model":"OR","required":!0,"rules":[v=>!!v||'Join Type is required',],"show":!0,},"operator":{"type":"select","label":"Operator","id":"operator","options":["<","<=","<>","=",">=",">","EXISTS","IN","IS NOT NULL","NULL","LIKE","NOT EXISTS","NOT IN","NOT LIKE"],"model":">=","required":!0,"rules":[v=>!!v||'Operator is required',],"show":!0,},"valueType":{"type":"select","label":"Value Type","id":"valueType","options":["Dependent SQL","SQL","VALUE"],"model":"SQL","required":!0,"rules":[v=>!!v||'Value Type is required',],"show":!0,},"dataType":{"type":"select","label":"Data Type","id":"dataType","options":["DATE","NUMBER","STRING"],"model":"NUMBER","required":!0,"rules":[v=>!!v||'Data Type is required',],"show":!0,},"format":{"type":"text","label":"Format","id":"format","model":"Config","required":!1,"show":!0,},"parameterMandatory":{"type":"select","label":"Parameter Mandatory","id":"parameterMandatory","options":["NO","YES"],"model":"YES","required":!0,"rules":[v=>!!v||'Parameter Mandatory is required',],"show":!0,},"link":{"type":"select","label":"Link","id":"link","options":["KB"],"model":"KB","required":!1,"show":!0,},"sequence":{'type':"text","label":"Sequence","id":"sequence","model":"SEQ1","required":!0,"rules":[v=>!!v||'Sequence is required',],"show":!0,},"value":{"type":"description_notes","label":"Value","id":"value","model":"VAL","required":!0,"rules":[v=>!!v||'Value is required',],"show":!0,}}},{'title':"Notes","columns":1,"fields":{"description":{"type":"description_notes","label":"Description","id":"description","required":!1,"model":'abcde',"show":!0,}}}]
const output = formFields.reduce((accumulator, { fields }) => {
return Object.assign(accumulator, Object.entries(fields)
.reduce((accumulatorInside, [key, { model }]) => {
accumulatorInside[key] = model;
return accumulatorInside;
}, {})
)
}, {});
console.log(output);
Or you can use loops
const output = {};
for (let index = 0; index < formFields.length; index++) {
for (let key in formFields[index].fields) {
if (formFields[index].fields.hasOwnProperty(key))
output[key] = formFields[index].fields[key].model;
}
}
console.log(output);
You could also do this with Array.prototype.forEach()(from #certainperformance answer, go up-vote that too)
const output = {};
formFields.forEach(({ fields }) => {
Object.entries(fields).forEach(([key, { model }]) => {
output[key] = model;
});
});
console.log(output);
The basic idea is the same regardless. You need to iterate over the properties and set the values.
From a performance standpoint: closures that move outside their scope are slower than functions that do not, and for...in loops are the fastest, but the most verbose to use.
BE CAREFUL! for...in loops do have some caveats! The reason I do the check for the own property is to prevent copying any prototypes. This is the one issue with the loop. You may instead want to use a for loop with the array returned with Object.getOWnPropertyNames() static method instead since it is safer and won't traverse prototypes, but it adds extra time complexity.
These are however considerations when you don't want to use side effects(Array.prototype.forEach()) or need to squeeze as MUCH speed as possible out of your code.