1

I'm looking to create a valid nested Json file, from an array, with unique keys value. Currently, I'm only able to to display the json without any nested structure.

I would like to display to the console the following structure :

{
    "Key" : "data1",
    "header" : {
        "title" : "data2",
        "tag1" : "data3",
        "tag2" : "data4"
    },
    "body" : {
        "text" : "data5"
    },
    "updates" : {
        "title" : "data6",
        "text" : "data7"
    },
    "footer" : {
        "title" : "data8",
        "row1" :{
            "col1" : {
                "title" : "data9",
                "text" : "data10"
            },
            "col2" : {
                "title" : "data11",
                "text" : "data12"
            }, 
            "col3" : {
                "title" : "data13",
                "text" : "data14"
            }
        },
        "row2" :{
            "col1" : {
                "title" : "data15",
                "text" : "data16"
            },
            "col2" : {
                "title" : "data17",
                "text" : "data18"
            }, 
            "col3" : {
                "title" : "data19",
                "text" : "data20"
            }
        },        
        "row3" :{
            "col1" : {
                "title" : "data22",
                "text" : "data23"
            },
            "col2" : {
                "title" : "data24",
                "titlebis" : "data25",
                "text" : "data26"
            }, 
            "col3" : {
                "title" : "data27",
                "text" : "data28"
            }
        },
        "row4" :{
            "col1" : {
                "title" : "data29"
            },
            "website" : "data30",
            "website-link" : "data31",
            "email" : "data38",
            "privacy" : "data32",
            "privacy-link" : "data33",
            "adr" : "data34",
            "adr2" : "data35"
        }        
    },
    "other" : {
        "short" : {
            "des" : "data36"
        },
        "promovideo" : "data37"
    }
}

here is what I already done:

  var data = [["Key", "data1"],
    ["header.title", "data2"],
    ["header.tag1", "data3"],
    ["header.tag2", "data4"],
    ["body.text", "data5"],
    ["updates.title", "data6"],  
    ["updates.text", "data7"], 
    ["footer.title", "data8"],
    ["footer.row1.col1.title", "data9"],
    ["footer.row1.col1.text", "data10"],
    ["footer.row1.col2.title", "data11"],
    ["footer.row1.col2.text", "data12"],
    ["footer.row1.col3.title", "data13"],
    ["footer.row1.col3.text", "data14"],
    ["footer.row2.col1.title", "data15"],
    ["footer.row2.col1.text", "data16"],
    ["footer.row2.col2.title", "data17"],
    ["footer.row2.col2.text2", "data18"],
    ["footer.row2.col3.title", "data19"],
    ["footer.row2.col3.text", "data20"],
    ["footer.row3.col1.title", "data22"],
    ["footer.row3.col1.text", "data23"],
    ["footer.row3.col2.title", "data24"],
    ["footer.row3.col2.title", "data25"],
    ["footer.row3.col2.text", "data26"],
    ["footer.row3.col3.title", "data27"],
    ["footer.row3.col3.text", "data28"],
    ["footer.row4.col1.title", "data29"],
    ["footer.row4.website", "data30"],
    ["footer.row4.website-link", "data31"],
    ["footer.row4.email", "data31"],
    ["footer.row4.privacy", "data32"], 
    ["footer.row4.privacy-link", "data33"],
    ["footer.row4.adr", "data34"],
    ["footer.row4.adr2", "data35"],
    ["other.short.des", "data36"],
    ["other.promovideo", "data37"],
  ];
  // console.log(data);

  data.sort(alphabetical); // Sort alphabetically our 2D array
  
  CreateAndDisplayJson(data);

  // Create a JSON file from Keys Trad Data
  function CreateAndDisplayJson(GetKeysTraductionArrayData) {
    var lenght = GetKeysTraductionArrayData.length;
  var output = "{\n";
  
  for (var i = 0; i < GetKeysTraductionArrayData.length; i++) {
    var key = GetKeysTraductionArrayData[i][0];
    var trad = GetKeysTraductionArrayData[i][1];
    
    var nameSplit = key.split("."); // Check how many times we need to indent json from Key
    
    if(nameSplit.length>1) { // The Key needs to be indented
      
      var closeBraket = "";
      var spacing = ""; // Json indentation
      var saveSpacingTab = []; // Closing indentation
      
      for (j=0; j <nameSplit.length; j++){ // We add the key + indentation
        output += spacing+"\""+nameSplit[j]+"\" : { \n";
        if (j==0 && i != GetKeysTraductionArrayData.length-1) { 
          closeBraket = spacing+"}, \n";
        } else {
          closeBraket = spacing+"} \n";
        }
        spacing +="   ";
        saveSpacingTab[j] = closeBraket;
        closingText = "";
        
        if (j==nameSplit.length-1) { // last indentation of the Key
          saveSpacingTab.reverse();
          for ( k=0; k < saveSpacingTab.length ; k++) { // We create the Bracket indentation
            closingText += saveSpacingTab[k];    
          }
          output += spacing+"\""+nameSplit[j]+"\" : " + "\""+trad +"\"\n" + closingText; // last Row
        }
      }
    } else {
      output += "\""+key+"\" : " + "\""+trad +"\", \n";
    }
  } 
  // output += "}" + outputCommented;
  output += "}";
  console.log(output);
  return output;
}

// Sort alphabetically our 2D array
function alphabetical(a, b) {
  var A = a[0];
  var B = b[0].toLowerCase(); 
  
  A = A.toLowerCase();
  B = B.toLowerCase();
  
  if (A < B) return -1;
  if (A > B) return 1;
  return 0;
}

5
  • 1
    I hate reading the same sentence multiple times, makes me think I'm going crazy.. Currently, I'm only able to to display..... Commented Jul 13, 2018 at 16:18
  • 1
    Maybe you could tell us what the array looks like that you are starting with. Commented Jul 13, 2018 at 16:21
  • Not sure what you are asking but have you tried JSON.stringify() ? Commented Jul 13, 2018 at 16:28
  • @keith we know you know we know you're going crazy :D Commented Jul 13, 2018 at 16:29
  • why do you need a sorting? Commented Jul 13, 2018 at 17:05

2 Answers 2

4

You can use forEach loop and inside split each key and then use reduce to build nested structure for each key.

var data = [["Key","data1"],["header.title","data2"],["header.tag1","data3"],["header.tag2","data4"],["body.text","data5"],["updates.title","data6"],["updates.text","data7"],["footer.title","data8"],["footer.row1.col1.title","data9"],["footer.row1.col1.text","data10"],["footer.row1.col2.title","data11"],["footer.row1.col2.text","data12"],["footer.row1.col3.title","data13"],["footer.row1.col3.text","data14"],["footer.row2.col1.title","data15"],["footer.row2.col1.text","data16"],["footer.row2.col2.title","data17"],["footer.row2.col2.text2","data18"],["footer.row2.col3.title","data19"],["footer.row2.col3.text","data20"],["footer.row3.col1.title","data22"],["footer.row3.col1.text","data23"],["footer.row3.col2.title","data24"],["footer.row3.col2.title","data25"],["footer.row3.col2.text","data26"],["footer.row3.col3.title","data27"],["footer.row3.col3.text","data28"],["footer.row4.col1.title","data29"],["footer.row4.website","data30"],["footer.row4.website-link","data31"],["footer.row4.email","data31"],["footer.row4.privacy","data32"],["footer.row4.privacy-link","data33"],["footer.row4.adr","data34"],["footer.row4.adr2","data35"],["other.short.des","data36"],["other.promovideo","data37"]]

let result = {}
data.forEach(([key, value]) => {
  key.split('.').reduce((r, k, i, arr) => {
    return r[k] || (r[k] = arr[i + 1] ? {} : value)
  }, result)
})

console.log(result)

Sign up to request clarification or add additional context in comments.

1 Comment

javascript has many problems, but things like this make it enjoyable :)
1

A non-ternary solution with reduce:

const data = [["Key","data1"],["header.title","data2"],["header.tag1","data3"],["header.tag2","data4"],["body.text","data5"],["updates.title","data6"],["updates.text","data7"],["footer.title","data8"],["footer.row1.col1.title","data9"],["footer.row1.col1.text","data10"],["footer.row1.col2.title","data11"],["footer.row1.col2.text","data12"],["footer.row1.col3.title","data13"],["footer.row1.col3.text","data14"],["footer.row2.col1.title","data15"],["footer.row2.col1.text","data16"],["footer.row2.col2.title","data17"],["footer.row2.col2.text2","data18"],["footer.row2.col3.title","data19"],["footer.row2.col3.text","data20"],["footer.row3.col1.title","data22"],["footer.row3.col1.text","data23"],["footer.row3.col2.title","data24"],["footer.row3.col2.title","data25"],["footer.row3.col2.text","data26"],["footer.row3.col3.title","data27"],["footer.row3.col3.text","data28"],["footer.row4.col1.title","data29"],["footer.row4.website","data30"],["footer.row4.website-link","data31"],["footer.row4.email","data31"],["footer.row4.privacy","data32"],["footer.row4.privacy-link","data33"],["footer.row4.adr","data34"],["footer.row4.adr2","data35"],["other.short.des","data36"],["other.promovideo","data37"]]

const result = data.reduce((all, [keys, val]) => {

    keys.split('.').reduce((obj, key, i, arr) => {

        if (i === arr.length - 1) {
            obj[key] = val;
        } else {
            if (!obj.hasOwnProperty(key)) {
                obj[key] = {};
            };
        }

        return obj[key];

    }, all);

    return all;

}, {});

console.log(result);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.