1

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

5
  • Please clarify your question. What do you mean with "it will be replaced with the current one"? Why remove only when "id = 4" when there are others that match? The value on "defaultOption[].item_select.value" means something? Commented Sep 15, 2021 at 19:14
  • So if you see id 4 and 6 are in selectedOption array but on expected_ouput should only have 6 because its the recent one , Assume if selectedOption had 4,6,7 the in expected_output it will be only 7 which is the recent one of that from defaultOptions[1].options Commented Sep 15, 2021 at 19:16
  • So thats why i am trying to get the last one expected_output.push(allMatches[allMatches.length - 1]) Commented Sep 15, 2021 at 19:17
  • How do you know if one is more recent than another? Do you mean greater than ? Commented Sep 15, 2021 at 19:21
  • the last one which got matched so will be getting all the 4,6,7 as matchedArray from that last one expected_output.push(allMatches[allMatches.length - 1]) this is where I am not getting, confused on how to solve this and get the desired result Commented Sep 15, 2021 at 19:24

2 Answers 2

1

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);

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

1 Comment

Seems lot of things to learn from this, let me check this to understand and will let you know, thanks for the help :) james
0

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)

Comments

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.