Reputation: 9652
I have a complex object where some array of objects that needs to be added ( grouping based on field and adding)
The format of both is shown below
//This is the source object where I need to add the below "arr" based on grouping
let filterObj = {
"feature": "test",
"filter": {
"and": [
{ "field": "field1","value": "1"}
]
}
};
//This array needs to be added to above object by grouping based on field
let obj = [
{"field": "field1","value": "2"},
{"field": "fiedl2","value": "3"},
{"field" : "field2","value": "4"},
{"field" : "field3","value" : "5"}
]
I want the output to be of following format:
var result = {
"feature": "test",
"filter": {
"and": [
{
"or" : [
{"field": "field1","value": "1"},
{"field": "field1", "value": "2"}
]
},
{
"or" : [
{"field": "field2","value": "3"},
{ "field": "field2","value": "4"},
]
},
{ "field": "field3", "value": "5"}
]
}
}
// The method that I have tried
filterObj.filter.and.or(...obj) ;// Does not work
I need to group them based on field values and then add them to the "or" array of objects(if field value is same). If not directly add it to the "and" array of objects.
Help would be appreciated.
Upvotes: 0
Views: 86
Reputation: 35222
filter.and
and obj
array together.reduce
the resulting array. field
as key. or
property, add the current object to the or
array. or
property, create an array with existing object in the accumulator and current object being iterated. Object.values()
on the resulting object to get the and
array.let filterObj={feature:"test",filter:{and:[{field:"field1",value:"1"}]}},
obj=[{field:"field1",value:"2"},{field:"field2",value:"3"},{field:"field2",value:"4"},{field:"field3",value:"5"}];
const merged = obj.concat(filterObj.filter.and || []).reduce((r, o) => {
if(r[o.field] && r[o.field].or)
r[o.field].or.push(o);
else if(r[o.field])
r[o.field] = { or: [r[o.field], o] }
else
r[o.field] = o;
return r;
}, {})
const filter = { and: Object.values(merged) },
{ feature } = filterObj;
console.log({ feature, filter })
.as-console-wrapper { max-height: 100% !important; top: 0; }
Upvotes: 1