-1

I have an array of keys

ex: var keyarray = [k1, k2, k3, ... ,kn];

Let o be an object;

I need to check the value of o[k1][k2][k3]...[kn]

I have tried the below methods:

Approach 1:

  1. Convert each element of keyArray into array so I get the below output var keyarray = [[k1], [k2], [k3], .... ,[kn]]
  2. Then execute keyarray.join(''); --> This results in a string such as k1k2k3...kn

Approach 2:

  1. Convert each element of keyArray into array so I get the below output var keyarray = [[k1], [k2], [k3], .... ,[kn]]
  2. Loop through the keyarray and append each value to a string so I get the below output s = "[k1][k2][k3]...[kn]"
  3. And then try o[s] --> returns undefined.

Looking for any kind of suggestions.

Edit: Adding a real time example for proper understanding.

I have JSON object like below

obj = {
  "history": [
    {
     "at": "someval",
     "by": "someval"
    }.
    {
     "at": "someval",
     "by": "someval"
    }  
  ]
 }

For the above I will have a keyArray like below

var keyArray = ["history", "0", "at"],

To access this I have to dynamically generate an object like below

obj[history][0][at]

Hope this helps.

Bharat Vk
  • 23
  • 11
  • 1
    [How do I format my posts using Markdown or HTML?](https://stackoverflow.com/help/formatting) – Andreas Oct 10 '20 at 06:53
  • Why wrapping the keys in arrays? Why joining them together? – Andreas Oct 10 '20 at 07:14
  • Taking keys from a csv export which gives keys in formats like history.0.at etc. So I'm splitting the string into an array and then trying to access the value. – Bharat Vk Oct 10 '20 at 07:23
  • So you already have a path. There are multiple questions about that setup: _access a property by path_ – Andreas Oct 10 '20 at 08:06

2 Answers2

1

You could try using javascript reduce method:

keyarray.reduce((output, key, index, array) => {
  if(index !== array.length){
    return output[key];
  }else{
    return output;
  }
},o)

where o is the initial object.

saran
  • 406
  • 2
  • 9
0

From what I understand, the object that you have is a deeply nested object and the array you have describes a path in that nesting. So, this method will return some result if it finds it, given the array of keys and the object (if there is indeed some "pot of gold" at the bottom of such deep nesting), however, if some key is not found at any stage, undefined will be returned.

Also, there can be a third test case where say the array has 3 keys, but the value of the 2nd key is not an object, but some primitive (string, number etc) value itself. In that case, that value will be returned. If we keep searching the keys even when the nesting isn't present, an error will be thrown.

You could try this:

const nestedObj = {
    "k1": {
        "k2": {
            "k3": "POT_OF_GOLD"
        }
    }
}

const arrOfKeys = ["k1","k2","k3"];

const secondArrOfKeys = ["k1","k4","k3"];

const thirdArrOfKeys = ["k1","k2","k3","k4","k5"];

//FIRST CASE - nesting is exactly as described in array of keys:
const endResult = arrOfKeys.reduce((result,key) => {
  if(typeof(result)==='object'){
    result = result[key];
  }
  return result;
},nestedObj);

//SECOND CASE - some key in array not present in nesting
const secondEndResult = secondArrOfKeys.reduce((result,key) => {
  if(typeof(result)==='object'){
    result = result[key];
  }
  return result;
},nestedObj);

//THIRD KEY - some key in array is not a nested obj, but a value itself
const thirdEndResult = thirdArrOfKeys.reduce((result,key) => {
  if(typeof(result)==='object'){
    result = result[key];
  }
  return result;
},nestedObj);


console.log(endResult);

console.log(secondEndResult);

console.log(thirdEndResult);

Looking at your specific example:

const obj = {
  "history": [
    {
     "at": "I WANT THIS VAL",
     "by": "someval"
    },
    {
     "at": "someval",
     "by": "someval"
    }  
  ]
 }
 
 const path = "history.0.at";
 
 const getValAtNestedPath = (__obj,__path) => {
   return __path.split('.').reduce((result,pathVal) => {
     if(typeof(result)==="object"){
       result = result[pathVal];
     }
     return result;
   },__obj)
 }
 
 console.log(getValAtNestedPath(obj,path));
Anuj Pancholi
  • 1,153
  • 8
  • 13