Home > Software design >  How select items in an object from an array of undesired key and create a new object with the result
How select items in an object from an array of undesired key and create a new object with the result

Time:10-21

Maybe it's a weird question, and maybe that exists and other way to make that... But, I've an initial Object on which I iterate on the key. For a special task, I've needed to have this Object without some key:value. For doing that I make an object with the key that I don't want.

I make this code pen for sample: https://codepen.io/charlene-bx/pen/qBXaqEL

const myInitialObject = {
  'key#one' : 'dataofanotherObject',
  'key#two' : 'dataofanotherObject',
  'key#three' : 'dataofanotherObject',
  'key#four' : 'dataofanotherObject',
  'key#five' : 'dataofanotherObject',
  'key#six' : 'dataofanotherObject',
  'key#seven' : 'dataofanotherObject',
  'key#eight' : 'dataofanotherObject',
  'key#nine' : 'dataofanotherObject',
  'key#ten' : 'dataofanotherObject'
}

const unDesiredKey = [
  'one',
  'four',
  'six'
]

// expected output:
// {
//  'key#two' : 'dataofanotherObject',
//  'key#three' : 'dataofanotherObject',
//  'key#five' : 'dataofanotherObject',
//  'key#seven' : 'dataofanotherObject',
//  'key#eight' : 'dataofanotherObject',
//  'key#nine' : 'dataofanotherObject',
//  'key#ten' : 'dataofanotherObject'
// }

I've found this solution but I can't find it very readable:

const filteredObject = Object.keys(myInitialObject)
      .filter(key => !unDesiredKey.map( el => !key.includes(el)).some(el => el===false))
      .reduce((accumulator, value) => ({...accumulator, [value]: myInitialObject[value]}), {})

CodePudding user response:

You could do this,

Use Array.prototype.map() on Object.entires() to filter out an array of desired key-value pair. And finally construct a new object from the key-value pair using Object.fromEntries()

const myInitialObject = {
    'key#one': 'dataofanotherObject',
    'key#two': 'dataofanotherObject',
    'key#three': 'dataofanotherObject',
    'key#four': 'dataofanotherObject',
    'key#five': 'dataofanotherObject',
    'key#six': 'dataofanotherObject',
    'key#seven': 'dataofanotherObject',
    'key#eight': 'dataofanotherObject',
    'key#nine': 'dataofanotherObject',
    'key#ten': 'dataofanotherObject'
}

const unDesiredKey = [
    'one',
    'four',
    'six'
]

const arr = Object.entries(myInitialObject).filter(x => !unDesiredKey.includes(x[0].split('#')[1]));

const finalObj = Object.fromEntries(arr);
console.log(finalObj)
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

CodePudding user response:

You could filter the entries and slice the key for comparing.

const
    data = { 'key#one': 'dataofanotherObject', 'key#two': 'dataofanotherObject', 'key#three': 'dataofanotherObject', 'key#four': 'dataofanotherObject', 'key#five': 'dataofanotherObject', 'key#six': 'dataofanotherObject', 'key#seven': 'dataofanotherObject', 'key#eight': 'dataofanotherObject', 'key#nine': 'dataofanotherObject', 'key#ten': 'dataofanotherObject' },
    unDesiredKey = ['one', 'four', 'six'],
    result = Object.fromEntries(Object
        .entries(data)
        .filter(([key]) => !unDesiredKey.includes(key.slice(key.indexOf('#')   1)))
    );

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
<iframe name="sif2" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

CodePudding user response:

You could filter the objects entries by keeping the ones that evaluate falsy to find(x => k.includes(x)) and use them to create a new object fromEntries.

const myInitialObject = {
  'key#one': 'dataofanotherObject',
  'key#two': 'dataofanotherObject',
  'key#three': 'dataofanotherObject',
  'key#four': 'dataofanotherObject',
  'key#five': 'dataofanotherObject',
  'key#six': 'dataofanotherObject',
  'key#seven': 'dataofanotherObject',
  'key#eight': 'dataofanotherObject',
  'key#nine': 'dataofanotherObject',
  'key#ten': 'dataofanotherObject'
}

const unDesiredKey = [
  'one',
  'four',
  'six'
];

const result = Object.fromEntries(Object.entries(myInitialObject)
  .filter(([k]) => !unDesiredKey.find(x => k.includes(x)))
);

console.log(result);
<iframe name="sif3" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

I could also accomplish this with reduce() if you like.

const obj = {
  'key#one': 'dataofanotherObject',
  'key#two': 'dataofanotherObject',
  'key#three': 'dataofanotherObject',
  'key#four': 'dataofanotherObject',
  'key#five': 'dataofanotherObject',
  'key#six': 'dataofanotherObject',
  'key#seven': 'dataofanotherObject',
  'key#eight': 'dataofanotherObject',
  'key#nine': 'dataofanotherObject',
  'key#ten': 'dataofanotherObject'
}

const unDesiredKey = [
  'one',
  'four',
  'six'
];

const result = Object.entries(obj).reduce((acc, [k, v]) => {
  if (unDesiredKey.find(x => k.includes(x))) return acc;
  acc = { ...acc, [k]: v }
  return acc;
}, {});

console.log(result);
<iframe name="sif4" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

CodePudding user response:

The provided approach uses the reduce method's accumulating object as carrier for the final result and omissibles as inexpensive/fast lookup structure (instead of e.g. an array based includes or find) for an undesired key ...

const myInitialObject = {
  'key#one' : 'dataofanotherObject',
  'key#two' : 'dataofanotherObject',
  'key#three' : 'dataofanotherObject',
  'key#four' : 'dataofanotherObject',
  'key#five' : 'dataofanotherObject',
  'key#six' : 'dataofanotherObject',
  'key#seven' : 'dataofanotherObject',
  'key#eight' : 'dataofanotherObject',
  'key#nine' : 'dataofanotherObject',
  'key#ten' : 'dataofanotherObject',
};
const unDesiredKey = [
  'one',
  'four',
  'six',
];

console.log(
  Object
    .entries(myInitialObject)
    .reduce(({ omissibles, result }, [key, value]) => ({

      omissibles,
      result: (key.split('#')[1] in omissibles)
        ? result
        : Object.assign(result, { [key]: value }),

    }), {

      omissibles: Object.fromEntries(unDesiredKey.map(key => [key, true])),
      result: {},

    }).result
);
.as-console-wrapper { min-height: 100%!important; top: 0; }
<iframe name="sif5" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

The lookup based approach also works for filtering the wanted entries (skipping the undesired ones) by providing the lookup as second thisArg property to the entry filtering task which results in a leaner code than the one above ...

const myInitialObject = {
  'key#one' : 'dataofanotherObject',
  'key#two' : 'dataofanotherObject',
  'key#three' : 'dataofanotherObject',
  'key#four' : 'dataofanotherObject',
  'key#five' : 'dataofanotherObject',
  'key#six' : 'dataofanotherObject',
  'key#seven' : 'dataofanotherObject',
  'key#eight' : 'dataofanotherObject',
  'key#nine' : 'dataofanotherObject',
  'key#ten' : 'dataofanotherObject',
};
const unDesiredKey = [
  'one',
  'four',
  'six',
];

console.log(
  Object.fromEntries(
    Object
      .entries(myInitialObject)
      .filter(function getValidEntryByBoundOmissibleKeys ([key]) {

        return !(key.split('#')[1] in this);

      }, Object.fromEntries(unDesiredKey.map(key => [key, true])))
  )
);
.as-console-wrapper { min-height: 100%!important; top: 0; }
<iframe name="sif6" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

  • Related