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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.