从Javascript数组创建嵌套的Json结构

时间:2018-07-13 16:16:49

标签: javascript arrays json

我想从一个数组中创建一个有效的嵌套Json文件,并使用唯一的键值。目前,我只能显示没有任何嵌套结构的json。

我想向控制台显示以下结构:

{
    "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"
    }
}

这是我已经做的:

  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;
}

2 个答案:

答案 0 :(得分:4)

您可以使用forEach循环并在split内部使用每个密钥,然后使用reduce为每个密钥构建嵌套结构。

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)

答案 1 :(得分:1)

使用<?xml version="1.0" encoding="utf-8"?> <data> <parent> <string >AAA</string> <nb><string >2</string></nb> <child1>aaa-1</child1> <child1>aaa-2</child1></parent> <parent> <string >BBB</string> <nb><string >1</string></nb> <child2>bbb-1</child2></parent> <parent> <string >CCC</string> <nb><string >0</string></nb></parent> </data> 的非三元解决方案:

    <?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >
    <xsl:template match="/">
        <xsl:comment>--- </xsl:comment>
        <xsl:comment>1 : parent nodes </xsl:comment>
        <xsl:for-each select ="/data/parent">
            <p> 
                <string>
                    <xsl:value-of select="string"/>
                </string>
                <xsl:comment>======================= </xsl:comment>
                <xsl:comment>2 : nb nodes (how many childs for a parent ) </xsl:comment>
                <xsl:for-each select ="/data/nb">
                    <xsl:if test="((position() &lt; 2) and (normalize-space(position() &gt;= 1)))">
                        <xsl:comment>Ex. for tThe first value only </xsl:comment>
                        <xsl:comment>How to do a dynamic test here (expected : AAA->3 (first nb value), BBB->1 (second nb value) ...)  ?</xsl:comment>
                        <xsl:comment>How to synchronise loop on parent and nb  ?</xsl:comment>
                        <nb>
                            <string>
                                <xsl:value-of select="string"/>
                            </string>
                        </nb>
                    </xsl:if>
                </xsl:for-each>
                <xsl:comment>======================= </xsl:comment>
                <xsl:comment>3 : child nodes </xsl:comment>
                <xsl:comment>How to manage the position and number of nodes to read ?</xsl:comment>
                <xsl:comment>Test 'string =AAA' is KO : always child2 </xsl:comment>
                <xsl:choose>
                    <xsl:when test='string =AAA'>
                        <xsl:copy-of select="/*/child1" />
                    </xsl:when>
                    <xsl:otherwise>
                        <xsl:copy-of select="/*/child2" />
                    </xsl:otherwise>
                </xsl:choose>               
            </p>
        </xsl:for-each>
    </xsl:template>
</xsl:stylesheet>