Javascript:嵌套数组映射和过滤以获得所需结果的有效方式

Javascript: Efficient way Nested Array mapping & filtering to get the desired results

我已经针对问题 2 尝试了以下解决方案以获得结果 2。使用相同代码获得结果(result1、result2 和 result3)的更有效方法是什么?

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": "[=11=] - ",
        "selected": false
      },
      {
        "name": " - ",
        "selected": false
      },
      {
        "name": " - ",
        "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
  }
]

我有问题 2 的解决方案,虽然我知道它不是很有效,那么有什么更好的解决方案吗?

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": "[=13=] - ",
        "selected": true
      },
      {
        "name": " - ",
        "selected": false
      },
      {
        "name": " - ",
        "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)

对于问题 3,第 1 组,选择了 none 个选项,相应地我应该得到结果 3。因此,只有选择了任何选项或价格具有范围(min/max/both min&max),结果在结果中显示。

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": "[=14=] - ",
        "selected": false
      },
      {
        "name": " - ",
        "selected": false
      },
      {
        "name": " - ",
        "selected": false
      }
    ],
    "range": {
      "min": 5,
      "max": 20
    }
  }
]

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

我想使用 reduce 来获得上面的这些 (result1, result2 & result3) 解决方案。有人可以帮我解决这个问题吗?

已编辑 以检查在同一组中选择了两个的情况,解决方案导致结果 1。

当在累加器对象中找到多个选定的 true 时,我添加了一个键,其中键名是 groupName 和选定的 name 的组合。如果没有选择 true 但具有 maxmin 值,则键名将只是 groupName。我使用最终对象的 Object.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": "[=10=] - ","selected": false},{"name": " - ","selected": false},{"name": " - ","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": "[=10=] -","selected": true},{"name": " - ","selected": false},{"name": " -","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": "[=10=] - ","selected": false},{"name": " - ","selected": false},{"name": " - ","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; }