[英]Convert nested array of array to nested array of object
I have currently the challenge to convert the following data:我目前面临转换以下数据的挑战:
{
"fieldname1": "value",
"fieldname3": [
"value 1",
[
[
"firstname",
"lastname"
]
]
],
"fieldname2": [
[
[
"value 3"
],
"full name"
]
]
}
into the following:进入以下:
{
"fieldname1": "value",
"fieldname3": {
"field3_sub1": "value 1",
"field3_sub2": [
{
"field3_sub2_1": "firstname",
"field3_sub2_2": "lastname"
}
]
},
"fieldname2": [
{
"field2_sub1": [
"value 3"
],
"field2_sub2": "full name"
}
]
}
I'm currently a bit lost how I could convert the source data into the expected object.我目前有点迷失如何将源数据转换为预期的 object。
I get the data from a sql query ( presto ).我从 sql 查询( presto )中获取数据。
The structured information ( fieldname2
and fieldname3
) aren't resolved, I get only the values in the response.结构化信息(
fieldname2
和fieldname3
)未解析,我只得到响应中的值。
The field position at root level is dynamic ( could be fieldname1
, fieldname2
, fieldname3
but also fieldname3
, fieldname1
, fieldname2
).根级别的字段 position 是动态的(可以是
fieldname1
, fieldname2
, fieldname3
也可以是fieldname3
, fieldname1
, fieldname2
)。
The value position inside fieldname2
and fieldname3
seems to be static. fieldname2
和fieldname3
中的值 position 似乎是 static。
I already solved the challenge to convert the given table schema into a JSONSchema:我已经解决了将给定表模式转换为 JSONSchema 的挑战:
{
"type": "object",
"properties": {
"fieldname2": {
"type": "array",
"items": {
"type": "object",
"properties": {
"field2_sub1": {
"type": "array",
"items": {
"type": "string"
}
},
"field2_sub2": {
"type": "string"
}
},
"additionalProperties": false,
"title": "fieldname2"
}
},
"fieldname1": {
"type": "string"
},
"fieldname3": {
"type": "object",
"properties": {
"field3_sub1": {
"type": "string"
},
"field3_sub2": {
"type": "array",
"items": {
"type": "object",
"properties": {
"field3_sub2_1": {
"type": "string"
},
"field3_sub2_2": {
"type": "string"
},
},
"additionalProperties": false,
"title": "field3_sub2"
}
}
},
"additionalProperties": false,
"title": "fieldname3"
}
},
"additionalProperties": false
}
Based on the JSONSchema I was able to generate a "model definition" which will be used in a code generator:基于 JSONSchema,我能够生成将在代码生成器中使用的“模型定义”:
{
"Fieldname2": {
"root": false,
"fields": {
"field2_sub1": {
"name": "field2_sub1",
"fieldType": "string[]",
"graphqlType": "[String]",
"nullable": true,
"filter": false
},
"field2_sub2": {
"name": "field2_sub2",
"fieldType": "string",
"graphqlType": "String",
"nullable": true,
"filter": true
}
}
},
"Field3_sub2": {
"root": false,
"fields": {
"field3_sub2_1": {
"name": "field3_sub2_1",
"fieldType": "string",
"graphqlType": "String",
"nullable": true,
"filter": true
},
"field3_sub2_2": {
"name": "field3_sub2_2",
"fieldType": "string",
"graphqlType": "String",
"nullable": true,
"filter": true
}
}
},
"Fieldname3": {
"root": false,
"fields": {
"field3_sub1": {
"name": "field3_sub1",
"fieldType": "string",
"graphqlType": "String",
"nullable": true,
"filter": true
},
"field3_sub2": {
"name": "field3_sub2",
"fieldType": "Field3_sub2[]",
"graphqlType": "[Field3_sub2]",
"nullable": true,
"filter": false
}
}
},
"Record": {
"root": true,
"fields": {
"fieldname2": {
"name": "fieldname2",
"fieldType": "Fieldname2[]",
"graphqlType": "[Fieldname2]",
"nullable": true,
"filter": false
},
"fieldname1": {
"name": "fieldname1",
"fieldType": "string",
"graphqlType": "String",
"nullable": true,
"filter": true
},
"fieldname3": {
"name": "fieldname3",
"fieldType": "Fieldname3",
"graphqlType": "Fieldname3",
"nullable": true,
"filter": false
}
}
}
}
Based on the comment from @nikhil, I spent an hour to create a running prototype.根据@nikhil 的评论,我花了一个小时来创建一个运行原型。
I have tested it successfully with the provided example data and real data.我已经用提供的示例数据和真实数据成功地测试了它。
It worked in both cases.它在两种情况下都有效。
const transformObject = (data, definition) => {
let res = {};
// get the field names from the definition
const definitionFields = Object.keys(definition);
for (let iElement = 0; iElement < data.length; iElement++) {
// get the current property name
const propName = definitionFields[ iElement ]
// get the definition for the current field
const fieldDefinition = definition[ propName ];
// in case the current value is a simple type, return it
if (fieldDefinition.type !== "array" && fieldDefinition.type !== "object") {
res[ propName ] = data[ iElement ];
}
// if the expected value for the current property is an object,
// run the object transformation
if (fieldDefinition.type === "object") {
res[ propName ] = transformObject(
data[ iElement ],
fieldDefinition.properties
);
}
// if the expected value for the current property is an array,
// run the array transformation
if (fieldDefinition.type === "array") {
res[ propName ] = transformArray(
data[ iElement ],
fieldDefinition.items
);
}
}
return res;
};
const transformArray = (data, definition) => {
// in case we have a simple type like string, number, etc.
// use the given data as return value
if (definition.type !== "object") {
return data;
}
// otherwise run the transform object function
// to generate the key/value pair
// NOTE: Since I don't have array of arrays in my usecase
// I didn't implemented the check for arrays
// i assume that the return value should be always
// an array of object or array of string/number/boolean
return data.map((ele) => {
return transformObject(ele, definition.properties);
});
};
const transform = (data, definition) => {
let res = {};
for (const [ key, value ] of Object.entries(data)) {
// get the current field definition from the schema
const fieldDefinition = definition[ key ];
// for simple types like string, number, etc. we don't have
// to run a transformation, just return the given value
if (fieldDefinition.type !== "object" && fieldDefinition.type !== "array") {
res[ key ] = value;
}
// in case of an object, run the object transformation
if (fieldDefinition.type === "object") {
res[ key ] = transformObject(value, fieldDefinition.properties);
}
// in case of an array, run the array transformation
if (fieldDefinition.type === "array") {
res[ key ] = transformArray(value, fieldDefinition.items);
}
}
return res;
};
const source = {
/**
* The provided data from the question
*/
}
const schema = {
/**
* the provided JSONSchema from the question
*/
}
const transformed = transform(source, schema.properties);
console.log(JSON.stringify(transformed, null, 2))
I hope I understood pretty enough.我希望我理解得足够充分。 Try playing with the array.group() method:
尝试使用 array.group() 方法:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/group https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/group
Good luck!!祝你好运!!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.