0

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.

1 Answer 1

1
  • concat the filter.and and obj array together.
  • reduce the resulting array.
  • Create an accumulator with each field as key.
  • If the key already exists and has a or property, add the current object to the or array.
  • If the key exists but doesn't have or property, create an array with existing object in the accumulator and current object being iterated.
  • If the key doesn't exist, add the key and set it to the current object.
  • Then use 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; }

Sign up to request clarification or add additional context in comments.

3 Comments

Thank you . I would Also want the feature and filter property in the result.
@vrosario added them now
Would the following statement if(r[o.field] && r[o.field].or) { r[o.field].or.push(o); } be used in case case?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.