[英]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}
請注意,我經常根據更簡單的getPaths
和path
函數來編寫pathEntries
。 這更干凈但效率較低,因為它需要對對象進行額外的遍歷。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.