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 但具有 max
或 min
值,则键名将只是 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; }
我已经针对问题 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 但具有 max
或 min
值,则键名将只是 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; }