簡體   English   中英

從嵌套的 JSON 構建鍵值數組

[英]Build key value array from nested JSON

我有以下 JSON 對象。 我需要在 javascript 中將其轉換為一級關聯數組。 (鍵值對)我寫了一個遞歸函數,但似乎無法讓它按照我想要的方式工作。 請參閱下面的示例以了解我所寫的內容:

{
    "Title" : "Test Match",
    "Players" : [
        {
            "ID" : 1,
            "Name" : "Ma Couella",
            "Results" : [2,2,0],
            "TeamMates" : [
                {
                    "ID" : 2,
                    "Age" : 24,
                    "LikesToWin" : false
                }
            ]
        }, {
            "ID" : 22,
            "Name" : "Shawn Kato",
            "Results" : [2,1,0],
            "TeamMates" : [
                {
                    "Name" : "Gerald Anderson",
                    "Age" : 24,
                    "LikesToWin" : false
                }
            ]
        }
    ],
    "Referees" : [
        {
            "ID" : 10,
            "Name" : "Janice Tieu",
            "YearsAsReferee" : 10,
            "EmploymentHistory" : [
                {
                    "JobTitle" : "Senior Referee",
                    "YearsOnTheJob" : 20,
                    "FavouriteMatchesRefereeed" : [
                        {
                            "Title" : "Duran vs Leonard 1",
                            "Year" : 1992,
                            "Description" : "I was refereeing the test match but I put on make up so Duran lost the bout."
                        }, {
                            "Title" : "Duran vs Leonard 2",
                            "Year" : 1994,
                            "Description" : "I was refereeing the second match but I put on make up so Duran lost another bout."
                        }
                    ]
                }, {
                    "JobTitle" : "Juniour Refereee",
                    "YearsOnTheJob" : 3,
                    "FavouriteMatchesRefereeed" : [
                        {
                            "Title" : "Mexican Figher Jones vs Anna Himley",
                            "Year" : 1972,
                            "Description" : "I coached this match. Hehe."
                        }, {
                            "Title" : "Jennifer from the block 2",
                            "Year" : 1982,
                            "Description" : "I coached this other match. Hehe."
                        }
                    ]
                }
            ]
        }
    ]
}

以下預期關聯數組的示例:

[
    "Title" => "Test Match",
    "Players[0][ID]" => 0,
    // rest of the array...
    "Players[0][Teammates][0][ID]" => 2,
    // rest of the array...
    "Referees[0][EmploymentHistory][FavouriteMatchesRefereeed][Title]" => "Duran vs Leonard 1"
]

這是我到目前為止所做的(javascript)

function converJSONToStrings(values, prevParent){
    console.log(values);
    var result = [];    

    for (var key in values)
    {
        var value = values[key];
        if(value.constructor === Array) {
            // console.log("Found object array in key", key );
            for(var x = 0; x<value.length; x++){
                result[key + '[' + x + ']'] = converJSONToStrings(value[x]);
            }
        } else if (typeof value == 'object') {
            for(var x in value){
                result[key + '[' + x + ']'] = converJSONToStrings(value[x]);
            }
        } else {
            result[key] = value;
        }
    }    

    return result;
}

終於想出了解決辦法! 下面的代碼...

 /** 
  * Formats the JSON result to an associative array, concatenating child and parent keys 
  */
 var convertJSONAssoc = function(obj, firstlevel) {
     // consider string, number and boolean values in JSON as the last
     // elements and can't be recursed into any further
     if (typeof obj == 'string' || typeof obj == 'number' || typeof obj == 'boolean') {
         var ab = [];
         var bc = {};
         bc.key = '';
         bc.val = obj;
         ab.push(bc);
         return ab;
     }

     // the top most call which builds the final result
     if (firstlevel) {
         var result = {};
         for (key in obj) {
             var val = obj[key];
             var s = convertJSONAssoc(val, false);
             for (var o = 0; o < s.length; o++) {
                 var v = s[o];
                 result[key + v['key']] = v['val'];
             }
         }
         return result;
     } else {
         // this is where the recursion happens. As long as objects are found,
         // we use the code below to keep on parsing obj keys
         var paths = [];
         for (var key in obj) {
             var val = obj[key];
             var s = convertJSONAssoc(val, false);
             for (var o = 0; o < s.length; o++) {
                 var v = s[o];
                 var de = {};
                 de.key = "[" + key + "]" + v['key'];
                 de.val = v['val'];
                 paths.push(de);
             }
         }
         return paths;
     }
 }

這是一個老問題,由於 OP 的編輯而重新出現。 現代技術使這比編寫問題時更容易一些。

這使用了兩個函數。 我用來將對象轉換為我認為更有用的類似格式的pathEntries ,例如

[
  [['Title'], 'Test Match'],
  [['Players', 0, 'ID'], 1],
  [['Players', 0, 'Name'], 'Ma Couella,
  // ...
  [['Referees', 0, 'EmploymentHistory', 1, 'FavouriteMatchesRefereeed', 1, 'Year'], 1982],
  [['Referees', 0, 'EmploymentHistory', 1, 'FavouriteMatchesRefereeed', 1, 'Description'], 'I coached this other match. Hehe.']
]

然后convert ,結合鍵映射和Object.fromEntries (如果您需要支持沒有它的環境,則很容易填充),將其轉換為您需要的格式。 它看起來像這樣:

 const pathEntries = (obj) => Object (obj) === obj ? Object .entries (obj) .flatMap ( ([k, x]) => pathEntries (x) .map (([p, v]) => [[k, ... p], v]) ) : [[[], obj]] const convert = (obj) => Object .fromEntries ( pathEntries (obj) .map (([k, v]) => [ k[0] + k .slice (1) .map (n => `[${n}]`) .join (''), v ]) ) const data = {Title: "Test Match", Players: [{ID: 1, Name: "Ma Couella", Results: [2, 2, 0], TeamMates: [{ID: 2, Age: 24, LikesToWin: !1}]}, {ID: 22, Name: "Shawn Kato", Results: [2, 1, 0], TeamMates: [{Name: "Gerald Anderson", Age: 24, LikesToWin: !1}]}], Referees: [{ID: 10, Name: "Janice Tieu", YearsAsReferee: 10, EmploymentHistory: [{JobTitle: "Senior Referee", YearsOnTheJob: 20, FavouriteMatchesRefereeed: [{Title: "Duran vs Leonard 1", Year: 1992, Description: "I was refereeing the test match but I put on make up so Duran lost the bout."}, {Title: "Duran vs Leonard 2", Year: 1994, Description: "I was refereeing the second match but I put on make up so Duran lost another bout."}]}, {JobTitle: "Juniour Refereee", YearsOnTheJob: 3, FavouriteMatchesRefereeed: [{Title: "Mexican Figher Jones vs Anna Himley", Year: 1972, Description: "I coached this match. Hehe."}, {Title: "Jennifer from the block 2", Year: 1982, Description: "I coached this other match. Hehe."}]}]}]} console .log (convert (data))
 .as-console-wrapper {max-height: 100% !important; top: 0}

請注意,我經常根據更簡單的getPathspath函數來編寫pathEntries 這更干凈但效率較低,因為它需要對對象進行額外的遍歷。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM