Home > OS >  Compare two array object and remove values
Compare two array object and remove values

Time:09-16

I have two arrays with objects in it which looks similar to:

let comp1 = [
    { optionKey: 'option1', displayName: '' },
    { optionKey: 'option2', displayName: '' },
    { optionKey: 'option3', displayName: '' },
    { optionKey: 'option4', displayName: '' },
    { optionKey: 'option5', displayName: '' },
    { optionKey: 'option6', displayName: '' },
    { optionKey: 'option7', displayName: '' },
  ];
let comp2 = [
    { option1Options: [] },
    { option2Options: [] },
    { option3Options: ['On', 'Off'] },
    { option4Options: ['Auto ', 'Off'] },
    { option5Options: [] },
    { option6Options: [] },
  ];

What I wanted to do was, if the value of each key in comp2's length in 0, I want to remove that key without Option index removed from comp1. So far, I was able to do is if each array has equal length

let comp1 = [
    { optionKey: 'option1', displayName: '' },
    { optionKey: 'option2', displayName: '' },
    { optionKey: 'option3', displayName: '' },
    { optionKey: 'option4', displayName: '' },
    { optionKey: 'option5', displayName: '' },
    { optionKey: 'option6', displayName: '' },
    { optionKey: 'option7', displayName: '' },
  ];
let comp2 = [
    { option1Options: [] },
    { option2Options: [] },
    { option3Options: ['On', 'Off'] },
    { option4Options: ['Auto ', 'Off'] },
    { option5Options: [] },
    { option6Options: [] },
  ];
  
comp1.forEach(function (item) {
    var index = comp2.findIndex(function (item2, i) {
        return item2[item.optionKey   'Options'] !== undefined;
    });
    if (index !== -1) {
        if (comp2[index][item.optionKey   'Options'].length === 0) {
            comp1.splice(index, 1);
        }
    }
});

console.log(comp1)

But in my case comp1 and comp2 length are different. How should I remove it by the key's value in comp1? Any help on this is apricated.

CodePudding user response:

You can simply filter() comp1 using a some() call to check if any options arrays exist in comp2. Here using optional chaining to avoid nonexistent elements in comp2

let comp1 = [{ optionKey: 'option1', displayName: '' }, { optionKey: 'option2', displayName: '' }, { optionKey: 'option3', displayName: '' }, { optionKey: 'option4', displayName: '' }, { optionKey: 'option5', displayName: '' }, { optionKey: 'option6', displayName: '' }, { optionKey: 'option7', displayName: '' },];
let comp2 = [{ option1Options: [] }, { option2Options: [] }, { option3Options: ['On', 'Off'] }, { option4Options: ['Auto ', 'Off'] }, { option5Options: [] }, { option6Options: [] },];

const result = comp1.filter(o =>
  comp2.some(option => option[`${o.optionKey}Options`]?.length > 0)
);

console.log(result);

CodePudding user response:

I think a simple combination of filter() and some() should get you there:

const comp1 = [
  { optionKey: 'option1', displayName: '' },
  { optionKey: 'option2', displayName: '' },
  { optionKey: 'option3', displayName: '' },
  { optionKey: 'option4', displayName: '' },
  { optionKey: 'option5', displayName: '' },
  { optionKey: 'option6', displayName: '' },
  { optionKey: 'option7', displayName: '' },
];

const comp2 = [
  { option1Options: [] },
  { option2Options: [] },
  { option3Options: ['On', 'Off'] },
  { option4Options: ['Auto ', 'Off'] },
  { option5Options: [] },
  { option6Options: [] },
];

const result = comp1.filter(({optionKey}) => comp2.some(v => v[`${optionKey}Options`]?.length));

console.log(result);

CodePudding user response:

You're splicing the array you're iterating over inside the forEach, which results in the array skipping the next element. For example, if you had items 1-2-3-4-5-6, and the test being performed would mean that all should be removed, you'd first remove 1, skip 2, remove 3, skip 4, remove 5, and skip 6.

While it would be possible to refactor so that the indices aren't creating this problem (such as a for loop), a better approach would be to iterate fully through comp2 first, identify the options to remove, then call .filter on comp1.

let comp1 = [
    { optionKey: 'option1', displayName: '' },
    { optionKey: 'option2', displayName: '' },
    { optionKey: 'option3', displayName: '' },
    { optionKey: 'option4', displayName: '' },
    { optionKey: 'option5', displayName: '' },
    { optionKey: 'option6', displayName: '' },
    { optionKey: 'option7', displayName: '' },
  ];
let comp2 = [
    { option1Options: [] },
    { option2Options: [] },
    { option3Options: ['On', 'Off'] },
    { option4Options: ['Auto ', 'Off'] },
    { option5Options: [] },
    { option6Options: [] },
  ];
  
const optionsToRemove = comp2
  .filter(obj => !Object.values(obj)[0].length)
  .map(obj => Object.keys(obj)[0].replace(/Options$/, ''));
const output = comp1.filter(
  ({ optionKey }) => !optionsToRemove.includes(optionKey)
);
console.log(output);

  • Related