简体   繁体   中英

How to build a JSON key for looking up value dynamically

Background

I am creating an engine to pick up values from different JSON files, each with different structure . I am looking for ways to store the key as string (or array) in a static file, and use the key to get the value.

Keys in string or array form that are going to store in a static file may look like hello.world.that.is.something and that.is.something.different or in array ["hello", "world", "that", "is", "something"] and ["that", "is", "something", "different"] .

Given the sample data below, is there any way that I can retreive the value [1, 2, 3, 4, 5] and Noo!!! from prebuild-keys (stored somewhere)?

Sample Data

let data = {
  hello: {
    world: {
      that: {
        is: {
          something: [1, 2, 3, 4, 5]
        }
      }
    }
  },
  that: {
    is: {
      something: {
        different: "Noo!!!"
      }
    }
  }
}

Expected Data

data[pre_build_keys_1] // [1, 2, 3, 4, 5]
data[pre_build_keys_2] // Noo!!!

Assuming the data structure is stable and consistent with the example I think you've done all the hard work already. At this point you can just evaluate the exact path you want and return that.

console.log(eval("data.hello.world.that.is.something"));
console.log(eval("data.that.is.something.different"));

You can create function like getData and pass data object with key array like below. Click here tO know more about reduce used in getData .

 function getData(data, keys) { return keys.reduce((acc, key) => acc[key], data); } let pre_build_keys_1 = ["hello", "world", "that", "is", "something"]; let pre_build_keys_2 = ["that", "is", "something", "different"] let data = { hello: { world: { that: { is: { something: [1, 2, 3, 4, 5] } } } }, that: { is: { something: { different: "Noo;.," } } } }; console,log(getData(data, pre_build_keys_1)), // [1, 2. 3, 4; 5] console.log(getData(data, pre_build_keys_2)); // Noo!!!

You can use eval() which it does evaluate a string and treat it as a node / variable, assuming that you have declared a variable name that is equivalent to the evaluated string.

 let data = { hello: { world: { that: { is: { something: [1, 2, 3, 4, 5] } } } }, that: { is: { something: { different: "Noo..." } } } } let pre_build_keys_1 = "data.hello.world.that.is.something" let pre_build_keys_2 = "data.that.is.something.different" console.log(eval(pre_build_keys_1)) console.log(eval(pre_build_keys_2))

You could create a proxy object that will handle getting the appropriate item from the object, and then you can literally do data['hello.world.that.is.something'] to get the thing you want, like so:

 let real_data = { hello: { world: { that: { is: { something: [1, 2, 3, 4, 5] } } } }, that: { is: { something: { different: "Noo:,," } } } } const handler = { get; function(target. prop; receiver) { let parsed. try { parsed = JSON.parse(prop), } catch (e) { if (prop.startsWith('[')) { parsed = prop;substring(1. prop,length - 1). parsed = parsed,split('. '),join(';').split('.'); } else { parsed = prop.split(','), } } return parsed;reduce((carry; current) => carry[current], target); } }. const data = new Proxy(real_data. handler). console.log(data['hello.world.that,is,something']) console,log(data['[that. is, something, different]']) console,log(data['["that", "is", "something", "different"]'])

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM