I have two arrays one is selectedOption and another is defaultOption, if the selectedOption id is present in any of the defaultOption array option property then it will be replaced with the current one . For an example i have added the expected_output
How could i achieve the expected output
let selectedOption = [
{
"count": 12,
"id": "16",
},
{
"count": 3,
"id": "4",
},
{
"count": 2,
"id": "8",
},
{
"count": 4,
"id": "15",
},
{
"count": 1,
"id": "6",
},
{
"count": 34,
"id": "19",
}
]
let defaultOption = [
{
"item_select": {
"value": "16",
},
"options": []
},
{
"item_select": {
"value": "4",
},
"options": [
{
"value": "4"
},
{
"value": "5"
},
{
"value": "6"
},
{
"value": "7"
}
]
},
{
"item_select": {
"value": "8",
},
"options": [
{
"value": "8"
},
{
"value": "9"
},
{
"value": "10"
},
{
"value": "11"
}
]
},
{
"item_select": {
"value": "12",
},
"options": [
{
"value": "12"
},
{
"value": "13"
},
{
"value": "14"
},
{
"value": "15"
}
]
}
]
What I have tried so far
let expected_output = []
selectedOption.forEach(current => {
isDefaultOptionMatched = defaultOption.find(defOpt => defOpt.options.some(opt => opt.value === current.id))
if(isDefaultOptionMatched?.options){
let allMatches = selectedOption.filter(selOpt => {
defaultOption.some(defOption => defOption.options.find(dop => dop.value === selOpt.id))
})
expected_output.push(allMatches[allMatches.length - 1])
}else{
expected_output.push(current)
}
})
What I am getting is 6 elements instead of 5, and its not right.
expected output what I am looking
Instead of 6 objects of expected_output array it will be 5 objects because the second last object id => 6 is part of defaultOption[1].options. The element which got removed is.
{
"count": 3,
"id": "4",
},
Which is part of defaultOption[1].options
expected_output = [
{
"count": 12,
"id": "16",
},
{
"count": 2,
"id": "8",
},
{
"count": 4,
"id": "15",
},
{
"count": 1,
"id": "6",
},
{
"count": 34,
"id": "19",
}
]
Any help is appreciated
CodePudding user response:
Here's a semi-hacky approach (I don't like bucketing the items and remembering the order to rebuild the array later) but it works
let selectedOption = [
{
"count": 12,
"id": "16",
},
{
"count": 3,
"id": "4",
},
{
"count": 2,
"id": "8",
},
{
"count": 4,
"id": "15",
},
{
"count": 1,
"id": "6",
},
{
"count": 34,
"id": "19",
}
];
let defaultOption = [
{
"item_select": {
"value": "16",
},
"options": []
},
{
"item_select": {
"value": "4",
},
"options": [
{
"value": "4"
},
{
"value": "5"
},
{
"value": "6"
},
{
"value": "7"
}
]
},
{
"item_select": {
"value": "8",
},
"options": [
{
"value": "8"
},
{
"value": "9"
},
{
"value": "10"
},
{
"value": "11"
}
]
},
{
"item_select": {
"value": "12",
},
"options": [
{
"value": "12"
},
{
"value": "13"
},
{
"value": "14"
},
{
"value": "15"
}
]
}
];
const result =
selectedOption.reduce((acc, el, order) => {
// bucket each element based on where it's found in defaultOption
const def = defaultOption.find(el2 => el2.options.some(el3 => el3.value === el.id));
if (def) {
const defId = def.item_select.value;
acc[defId] = {...el, order};
} else {
acc[el.id] = {...el, order};
}
return acc;
}, {});
// fix the order and remove the order field
const finish = Object.values(result).sort((a, b) => a.order - b.order).map(({order, ...rest}) => rest);
console.log(finish);
CodePudding user response:
let selectedOption = [
{
"count": 12,
"id": "16",
},
{
"count": 3,
"id": "4",
},
{
"count": 2,
"id": "8",
},
{
"count": 4,
"id": "15",
},
{
"count": 1,
"id": "6",
},
{
"count": 34,
"id": "19",
}
]
let defaultOption = [
{
"item_select": {
"value": "16",
},
"options": []
},
{
"item_select": {
"value": "4",
},
"options": [
{
"value": "4"
},
{
"value": "5"
},
{
"value": "6"
},
{
"value": "7"
}
]
},
{
"item_select": {
"value": "8",
},
"options": [
{
"value": "8"
},
{
"value": "9"
},
{
"value": "10"
},
{
"value": "11"
}
]
},
{
"item_select": {
"value": "12",
},
"options": [
{
"value": "12"
},
{
"value": "13"
},
{
"value": "14"
},
{
"value": "15"
}
]
}
]
let expected_output = []
defaultOption.forEach(defOption => {
let allMatches = selectedOption.filter(selOpt => defOption.options.find(dop => dop.value === selOpt.id))
if(allMatches.length > 0){
expected_output.push(allMatches[allMatches.length - 1])
}
})
selectedOption.forEach(selOpt => {
let isDefaultOptionMatched = defaultOption.find(defOpt => defOpt.options.some(opt => opt.value === selOpt.id))
if(!isDefaultOptionMatched){
expected_output.push(selOpt)
}
})
console.log(expected_output)