Search code examples
javascriptobject

How do I create this complex Javascript variable


I would like to create a complex Javascript variable like this:

var e = {record: {role: {individual: {tag: value}}}};

where record, role, individual, and value are variables which come from an array. At the end it should look like this:

var e = {1: {2: {1: {name: Joseph Quincy}
                    {age: 20}    

                 2: {name: Mary Poppins}
                    {age: 40}

                 3: {name: Sebastian Quincy}
                    {age: 60}

            {3: {1: ... and so forth

The array was derived from data as shown below, where the first number is record, second is role, and third is individual, the tag is name and age and the value is after the space:

name_1_2_1 Joseph Jones
name_1_2_2 Mary Poppins
name_1_2_3 Sebastian Quincy
age_1_2_1 20
age_1_2_2 40
age_1_2_3 60

The arrays look like for name_1_2_1 Joseph Jones:

key_value_ary = (name_1_2_1, Joseph James);
tag_rri_ary = (name, _1_2_1);
r_r_i_ary = (1, 2, 1);

Hence

value      = key_value_ary[1]; -> Joseph Jones
tag        = tag_rri_ary[0];   -> name
record     = r_r_i_ary[0];     -> 1
role       = r_r_i_ary[1];     -> 2
individual = r_r_i_ary[2];     -> 1

I have all these objects created but I don't know how to write to the final variable "e". I have the code below that figure out the different values. I write one line at a time so the record may exist already from a previous entry.

if (r_r_i_ary.length == 3) {
        var tag = tag_rri_ary[0];
        console.log("TAG", tag);
        var value = key_value_ary[1];
        console.log("VALUE", value);
        const a = {};
        a[tag] = value; // tag value
        console.log("AAA", a);
        const b = {};
        var individual = r_r_i_ary[2]; // individual
        b[individual] = a;
        console.log("BBB", b);
        const c = {};
        var role = r_r_i_ary[1]; // role
        c[role] = b;
        console.log("CCC", c);
        const d = {};
        var record = r_r_i_ary[0]; // record
        d[record] = c;
        console.log("DDD", d);
        e=????? 
      }

I obtained this from the console as one of the examples but I need to concatenate all together in one variable:

{
    "4": {
        "1": {
            "2": {
                "will_plac": "Atibaia, São Paulo, Brasil"
            }
        }
    }
}

How do I do that?

Thanks!


Solution

  • Similar to Valery's, but first I structure the data into a way that is useful:

    [
      {
        "route": [
          "1",
          "2",
          "3"
        ],
        "key": "age",
        "val": "60"
      }
    ]
    

    Using split and other basic array functions to join what's left back together.

    Then I use a function with a while loop to work through the array of the route key before setting that value.

    const data = [
      `name_1_2_1 Joseph Jones`,
      `name_1_2_2 Mary Poppins`,
      `name_1_2_3 Sebastian Quincy`,
      `age_1_2_1 20`,
      `age_1_2_2 40`,
      `age_1_2_3 60`,
    ];
    
    const keyedData = data.map(line => {
      const bits = line.split(" ");
      
      const route = bits.shift(); // name_1_2_1
    
      const keyBits = route.split("_"); // [name, 1, 2, 1]
      const key = keyBits.shift(); // name
      
      return {
        route: keyBits,
        key,
        val: bits.join(' ') // the left over `Joseph Jones`
      }
    })
    
    
    function buildObject(data){
      const finalObject = {}
      
      data.forEach(item => {
        // Reset the target for this item to the `root` object
        let target = finalObject;
        while(item.route.length){
          let routeFragment = item.route.shift();
          // If the target doesn't have a property on this key, create one
          if(!target.hasOwnProperty(routeFragment)){
            target[routeFragment] = {};
          }
          // Now set the new target 
          target = target[routeFragment];
        }
        // Finally, update that value.
        target[item.key] = item.val;
      })
      
      return finalObject
    }
    
    const result = buildObject(keyedData);
    console.log(result);