Home > Mobile >  filtering an array based on another array based on the order
filtering an array based on another array based on the order

Time:09-16

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)

  • Related