0

Let's say I have the following object:

const obj = {
  'myApi': ['keyOne', 'keyTwo'],
  'myApi.keyOne': ['three', 'four'],
  'myApi.keyTwo': [...],
  'myApi.keyOne.three': [...]
  'myApi.keyOne.four': [...]
}

Now, based on the following string:

const str = "if(myApi.keyOne.three"

I want to match the correct object key, but from right to left. So, in the above example, I want to get obj["myApi.keyOne.three"].

indexOf or str.test methods will not work because they will catch myApi and myApi.keyOne also.

Note that it could be any string, the str is just an example. For example:

while(myApi.keyOne.three) {} // should match obj["myApi.keyOne.three"]
if(myApi.keyOne) {} // should match obj["myApi.keyOne"]

etc.

How can I do this?

undefined
  • 6,366
  • 12
  • 46
  • 90

4 Answers4

1

To get the key, use a regular expression to match myApi, followed by any number of repeated groups of (a period followed by word characters). Then, you can just access the appropriate key on the object:

const obj = {
  'myApi': ['keyOne', 'keyTwo'],
  'myApi.keyOne': ['three', 'four'],
  'myApi.keyOne.three': ['foobar']
};

function getVal(str) {
  const key = str.match(/myApi(?:\.\w+)*/)[0];
  console.log(obj[key]);
  return obj[key];
}
getVal("if(myApi.keyOne.three");
getVal("while(myApi.keyOne.three) {}");
getVal("if(myApi.keyOne) {}");
CertainPerformance
  • 356,069
  • 52
  • 309
  • 320
1

Search for the key entry in the pattern:

var result = “”;
Object.keys(obj).forEach(function(key) {
    if (str.indexOf(key) !== -1 && key.length > result.length) result = key;
});

console.log(obj[result]);
stdob--
  • 28,222
  • 5
  • 58
  • 73
1

To make things more dynamic (even if there's no guarantee about myApi):

function findStuff(str, obj) {
  const keys = Object.keys(obj);
  keys.sort((a, b) => b.length - a.length);
  // https://stackoverflow.com/questions/3561493/is-there-a-regexp-escape-function-in-javascript
  const re = new RegExp(keys.map(key => key.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&')).join('|'));
  const match = str.match(re);
  return match && match[0];
}

const obj = {
  'myApi': ['keyOne', 'keyTwo'],
  'myApi.keyOne': ['three', 'four'],
  'myApi.keyTwo': [""],
  'myApi.keyOne.three': ["THREE"],
  'myApi.keyOne.four': [""]
}

console.log(findStuff('while(myApi.keyOne.three) {}', obj));

We take all the keys from the object, then sort them by descending length (so the longest will be matched first). Then regexp-escape them and stick them together in a regexp alternation.

Amadan
  • 191,408
  • 23
  • 240
  • 301
0

You can use a regular expression like

myApi(\.\w+)*

Details:

  • myApi - matches the "myApi" string
  • (\.\w+)* - matches 0 or more repetitions of those alphanumeric strings which follows a period (.) character
  • const obj = {
      'myApi': ['keyOne', 'keyTwo'],
      'myApi.keyOne': ['three', 'four'],
      'myApi.keyTwo': ['someVlaue1'],
      'myApi.keyOne.three': ['someVlaue2'],
      'myApi.keyOne.four': ['someVlaue3']
    }
    
    var str1 = 'while(myApi.keyOne.three) {}';
    var str2 = 'if(myApi.keyOne) {}';
    
    var regex = /myApi(\.\w+)*/g;
    
    var val1 = obj[ str1.match(regex)[0] ];
    var val2 = obj[ str2.match(regex)[0] ];
    
    console.log(val1);
    console.log(val2);
    vrintle
    • 5,501
    • 2
    • 16
    • 46