-1

Let's say I have this object:

const someProps = { darkMode: true, underlineMistakes: false, spellingView: (...), grammerView: (...) };

I do not necessarily know the names of any of the props, except that 1+ end in 'View'.

and I want to only destructure the keys that end in 'view', which I'd like to do something like:

const propsEndingInView = Object.keys(someProps).filter(prop => !prop.endsWith('View');
const {
  ...nonViewProps, // darkMode, underlineMistakes
  propsEndingInView // {spellingView: (...), grammerView: (...)}
} = someProps; 

I need to somehow separate the two kinds of props, preferably while

I can't think how to do this, or even if it's possible.

AncientSwordRage
  • 7,086
  • 19
  • 90
  • 173
  • 4
    If you don't know the names of the keys, why do you want to destructure them into variables of which you also won't know the names?! Say you would succeed in that, then what? What will you write afterwards to access those variables you have just created? – deceze May 28 '20 at 12:08
  • @deceze I'm trying to build a generic Tabs component, and basing the label of the tab off of the prop. I just realised what you mean by this, let me fix the example. – AncientSwordRage May 28 '20 at 12:09
  • You could do this without desctructuring, is there a particular reason you don't want to handle it 'manually'? – Dane Brouwer May 28 '20 at 12:14
  • 1
    When you have `propsEndingInView` , you already have the keys with you. post that you can simply get the values like `someProps[propsEndingInView[0]]` and so on. however I think you might want to map on those – Shubham Khatri May 28 '20 at 12:16

3 Answers3

2

Destructuring is just way to get the properties you already know. You can't do this with destructuring. You can create a custom method to filter out the keys to get a subset of the object

const someProps = {
  darkMode: true,
  underlineMistakes: false,
  spellingView: 'spellingView',
  grammerView: 'grammerView'
};

const subset = Object.fromEntries(
  Object.entries(someProps).filter(([k]) => k.endsWith('View'))
)

console.log(subset)
adiga
  • 34,372
  • 9
  • 61
  • 83
1

This cannot be done by destructuring, but you can write some code to do it. For example:

const extract = (obj, regex) => 
  Object
    .entries(obj)
    .filter(([k]) => (typeof k === 'string') && regex.test(k))
    .reduce((out, [k, v]) => (
      out[k] = v,
      out
    ), {})

const someProps = { darkMode: true, underlineMistakes: false, spellingView: '(...)', grammerView: '(...)' };

const propsEndingInView = extract(someProps, /View$/)
console.log(propsEndingInView)
FZs
  • 16,581
  • 13
  • 41
  • 50
1

If I understand correctly you want to end up with an object that only contains properties from someProps whose names end in View. You can do something like:

const viewProps = Object.keys(someProps).reduce((props, propName) => {
  // Here we check whether propName ends in View
  // If it does we add it to the object, if not we leave the object as it is
  return propName.match(/View$/) ? { ...props, [propName]: someProps[propName] } : props;
}, {});

Does that help? You can find the documentation about Array.reduce here.

Ján Jakub Naništa
  • 1,880
  • 11
  • 12