1

I have tried the below solution for question2 to get result2. What would be a more efficient way to get both the result (result1, result2 & result3) with the same code?

question1 = [
  {
    "groupName": "Group 1",
    "id": "group1",
    "options": [
      {
        "name": "Cat1",
        "selected": true
      },
      {
        "name": "Cat2",
        "selected": true
      },
      {
        "name": "Cat3",
        "selected": false
      },
      {
        "name": "Cat4",
        "selected": false
      }
    ]
  },
  {
    "groupName": "Group 2",
    "id": "Brand",
    "options": [
      {
        "name": "brand1",
        "selected": false
      },
      {
        "name": "brand2",
        "selected": true
      },
      {
        "name": "brand3",
        "selected": false
      }
    ]
  },
  {
    "groupName": "Group 3",
    "id": "Price",
    "options": [
      {
        "name": "$0 - $9",
        "selected": false
      },
      {
        "name": "$9 - $19",
        "selected": false
      },
      {
        "name": "$20 - $29",
        "selected": false
      }
    ],
    "range": {
      "min": 5,
      "max": 20
    }
  }
]

result1 = [{
    "groupName": "Group 1",
    "id": "group1",
    "name": "Cat1",
  },
  {
    "groupName": "Group 1",
    "id": "group1",
    "name": "Cat2",
  },
  {
    "groupName": "Group 2",
    "id": "Brand",
    "name": "brand2",
  },
  {
    "groupName": "Group 3",
    "id": "Price",
    "min": 5,
    "max": 20
  }
]

I have a solution for question2, although I know it's not very efficient, so what could be a better solution?

question2 = [
  {
    "groupName": "Group 1",
    "id": "group1",
    "options": [
      {
        "name": "Cat1",
        "selected": true
      },
      {
        "name": "Cat2",
        "selected": false
      },
      {
        "name": "Cat3",
        "selected": false
      },
      {
        "name": "Cat4",
        "selected": false
      }
    ]
  },
  {
    "groupName": "Group 2",
    "id": "Brand",
    "options": [
      {
        "name": "brand1",
        "selected": false
      },
      {
        "name": "brand2",
        "selected": true
      },
      {
        "name": "brand3",
        "selected": false
      }
    ]
  },
  {
    "groupName": "Group 3",
    "id": "Price",
    "options": [
      {
        "name": "$0 - $9",
        "selected": true
      },
      {
        "name": "$9 - $19",
        "selected": false
      },
      {
        "name": "$20 - $29",
        "selected": false
      }
    ],
    "range": {
      "min": null,
      "max": null
    }
  }
]


const selected2 = question2.map(group => group.options.filter(option => option.selected).map(option => ({groupName: group.groupName, id: group.id, name: option.name}))).flat(1)


console.log(selected2)

For question3, group 1, none of the options is selected and correspondingly I should get result3. So, only if any of the options are selected or the price has a range (either min/max/both min&max), it is displayed in the result.

question3 = [
  {
    "groupName": "Group 1",
    "id": "group1",
    "options": [
      {
        "name": "Cat1",
        "selected": false
      },
      {
        "name": "Cat2",
        "selected": false
      },
      {
        "name": "Cat3",
        "selected": false
      },
      {
        "name": "Cat4",
        "selected": false
      }
    ]
  },
  {
    "groupName": "Group 2",
    "id": "Brand",
    "options": [
      {
        "name": "brand1",
        "selected": false
      },
      {
        "name": "brand2",
        "selected": true
      },
      {
        "name": "brand3",
        "selected": false
      }
    ]
  },
  {
    "groupName": "Group 3",
    "id": "Price",
    "options": [
      {
        "name": "$0 - $9",
        "selected": false
      },
      {
        "name": "$9 - $19",
        "selected": false
      },
      {
        "name": "$20 - $29",
        "selected": false
      }
    ],
    "range": {
      "min": 5,
      "max": 20
    }
  }
]

result3 = [
  {
    "groupName": "Group 2",
    "id": "Brand",
    "name": "brand2",
  },
  {
    "groupName": "Group 3",
    "id": "Price",
    "min": 5,
    "max": 20
  }
]

I want to use reduce to get these above (result1, result2 & result3) solutions. Could someone help me with this?

Edited to check scenario where two are selected in the same group, solution resulting in result1.

1 Answer 1

1

When multiple selected trues found in the accumulator object I'm adding a key where keyname is a combination of groupName and selected name. If no selected true but has max or min values the key name will be just groupName. I take Object.values() of the final object to get the array of values.

const question1 = [{"groupName": "Group 1","id": "group1","options": [{"name": "Cat1","selected": true},{"name": "Cat2","selected": true},{"name": "Cat3","selected": false},{"name": "Cat4","selected": false}]},{"groupName": "Group 2","id": "Brand","options": [{"name": "brand1","selected": false},{"name": "brand2","selected": true},{"name": "brand3","selected": false}]},{"groupName": "Group 3","id": "Price","options": [{"name": "$0 - $9","selected": false},{"name": "$9 - $19","selected": false},{"name": "$20 - $29","selected": false}],"range": {"min": 5,"max": 20}}]

const question2 = [{"groupName": "Group 1","id": "group1","options":[{"name":"Cat1","selected": true},{"name": "Cat2","selected": false},{"name":"Cat3","selected": false},{"name": "Cat4","selected": false}]},{"groupName": "Group 2","id": "Brand","options": [{"name":"brand1","selected":false},{"name": "brand2","selected": true},{"name": "brand3","selected": false}]},{"groupName": "Group 3","id": "Price","options": [{"name": "$0 -$9","selected": true},{"name": "$9 - $19","selected": false},{"name": "$20 -$29","selected": false}],"range": {"min": null,"max": null}}]

const question3 = [{"groupName": "Group 1","id": "group1","options": [{"name": "Cat1","selected": false},{"name": "Cat2","selected": false},{"name": "Cat3","selected": false},{"name": "Cat4","selected": false}]},{"groupName": "Group 2","id": "Brand","options": [{"name": "brand1","selected": false},{"name": "brand2","selected": true},{"name": "brand3","selected": false}]},{"groupName": "Group 3","id": "Price","options": [{"name": "$0 - $9","selected": false},{"name": "$9 - $19","selected": false},{"name": "$20 - $29","selected": false}],"range": {"min": 5,"max": 20}}]


const formatter = (arr) => {
    return Object.values(arr.reduce((acc,curr) => {
    
    const hasMax = curr.range && curr.range.max;
    const hasMin = curr.range && curr.range.max
    const filtered = curr['options'].filter((option) => option.selected);
    
    if (filtered.length) {
        filtered.forEach((el) => {
        acc[curr.groupName+el.name] = {id: curr.id,groupName: curr.groupName,name: el.name}
      })
    }
    else if (hasMin || hasMax){
        acc[curr.groupName] = {id: curr.id,groupName: curr.groupName}
      if(hasMax) acc[curr.groupName]['max'] = curr.range.max
      if(hasMin) acc[curr.groupName]['min'] = curr.range.min
    }
  return acc;
},{}))
}

const result1 = formatter(question1)
const result2 = formatter(question2)
const result3 = formatter(question3)

console.log(result1)
console.log(result2)
console.log(result3)
.as-console-wrapper { max-height: 100% !important; top: 0; }

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

7 Comments

Thank you very much, this is really helpful. I edited for question3 (another scenario). Could you help me with that? –
Got it, thank you very much. Yes, I do have a scenario where there could be two selected values in the same group. (The rest scenarios are covered above with your solution)
Edited question1 & result1.
i mean there are so many cases what happens if there are 2 trues and it also has min max values
Wrt Group 3, it's either min/max/min&max or only one selected, but wrt other groups there could be two options selected (multi-select). This is the only scenario that isn't covered. The rest are covered in your solution.
|

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.