我有以下JSON对象。我需要将它在javascript中转换为一级关联数组。 (键值对)我写了一个递归函数,但似乎无法按照我想要的方式工作。
{
"Title" : "Test Match",
"Players" : [
{
"ID" : 1,
"Name" : "Igi Manaloto",
"Results" : [2,2,0],
"TeamMates" : [
{
"ID" : 2,
"Name" : "John Ibarra",
"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,
"Players[0][Name]" => "Igi Manaloto",
// rest of the array...
"Players[0][Teammates][0][ID]" => 2,
"Players[0][Teammates][0][Name]" => "John Ibarra",
// 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;
}
答案 0 :(得分:1)
终于想出了一个解决方案!代码如下......
/**
* 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;
}
}
答案 1 :(得分:1)
这是一个老问题,由于 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}
注意 I often write pathEntries
就更简单的 getPaths
和 path
函数而言。这更简洁但效率较低,因为它需要对对象进行额外的遍历。