0

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.

3 Answers 3

1

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

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

Comments

1

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

Comments

0

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

1 Comment

Thank you for your help and to fully explain the answer.

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.