如何根据 JavaScript 中的键转换对象?
How to convert object based on keys in JavaScipt?
我有以下格式的对象。我在处理了一些数据之后得到了这个对象,并且密钥已经从上述数据中检索到了。这些键指的是一个数据结构,用“.”表示。句号。我正在寻找一种可以将此对象更改为第二个对象结构的方法,因为这样可以更轻松地将此数据保存在后端。
{
"pageId":"6103a64eaa0f0228d5487d8d",
"answer":{
"PremiumServices:AmazonPrime":"1",
"paymentMethod:Paypal:PaypalUsageCode":[
"2"
],
"PaymentsToIncurCode":[
"1",
"2"
],
"null":[
"10",
"4",
"7"
],
"paymentMethod:mobileWalletCodes":[
"10"
],
"paymentMethod:mobileWalletCodes.0":[
"17"
],
"paymentMethod:mobileWalletCodes.1":[
"17"
],
"paymentMethod:mobileWalletCodes.2":[
"16"
],
"paymentMethod:mobileWalletCodes.3":[
"16"
]
}
},
我想把它转换成下面的格式。
{
"pageId": "6103a64eaa0f0228d5487d8d",
"answer": {
"PremiumServices": {
"AmazonPrime": "1"
},
"paymentMethod": {
"mobileWalletCodes": {
"0": [
"17"
],
"1": [
"17"
],
"2": [
"16"
],
"3": [
"16"
]
}
},
"PaymentsToIncurCode": [
"1",
"2"
],
"PaymentsToIncuCode": [
"10",
"4",
"7"
]
}
}
是否有库或函数可以将第一个对象转换为第二个对象的格式?
属性有多个自定义转换步骤。这是我能够实现的最通用的方法:
const json = `{
"pageId":"6103a64eaa0f0228d5487d8d",
"answer":{
"PremiumServices:AmazonPrime":"1",
"paymentMethod:Paypal:PaypalUsageCode":[
"2"
],
"PaymentsToIncurCode":[
"1",
"2"
],
"null":[
"10",
"4",
"7"
],
"paymentMethod:mobileWalletCodes":[
"10"
],
"paymentMethod:mobileWalletCodes.0":[
"17"
],
"paymentMethod:mobileWalletCodes.1":[
"17"
],
"paymentMethod:mobileWalletCodes.2":[
"16"
],
"paymentMethod:mobileWalletCodes.3":[
"16"
]
}
}`;
const data = JSON.parse(json);
const result = {
pageId: data.pageId,
answer: {
PremiumServices: Object
.fromEntries(Object
.entries(data.answer)
.filter(([key]) =>
key.startsWith('PremiumServices')
).map(([key, value]) =>
[key.split(':')[1], value]
)
),
paymentMethod: Object
.fromEntries(Object
.entries(data.answer)
.filter(([key]) =>
key.startsWith('paymentMethod:mobileWalletCodes.')
).map(([key, value]) =>
[key.split('.')[1], value]
)
),
PaymentsToIncurCode: data.answer.PaymentsToIncurCode,
PaymentsToIncuCode: data.answer.null
}
};
console.log(result);
const resultJson = JSON.stringify(result);
console.log(resultJson);
.as-console-wrapper { min-height: 100%!important; top: 0; }
这是一个使用ramda
的函数式递归方法
const convertObjectStructure = R.compose(
R.reduce(R.mergeDeepWith((x, y) => R.is(Object, x) && R.is(Array, y) ? x : R.is(Object, y) && R.is(Array, x) ? y : R.concat(x, y)), {}),
R.map(([k, v]) => R.assocPath(R.split(/\.|:/, k), R.when(R.both(R.is(Object), R.compose(R.complement, R.is)(Array)), convertObjectStructure)(v), {})),
R.toPairs
)
convertObjectStructure(JSON.parse(json))
没有我希望的那么干净,但是已经是午夜了。
中查看
更新 #1
The output is not the sames as the OP's.. –
Keith
const renameKeysDeep = R.curry((mapping, input) => R.compose(
R.reduce((acc, [k, v]) => {
if (!(k in mapping)) return {...acc, [k]: v};
if (R.is(Object)(mapping[k])) return {...acc, [k]: renameKeysDeep(mapping[k], v)};
return {...acc, [mapping[k]]: v};
}, {}),
R.toPairs
)(input))
const convertObjectStructure = R.compose(
R.reduce(R.mergeDeepWith((x, y) => R.is(Object, x) && R.is(Array, y) ? x : R.is(Object, y) && R.is(Array, x) ? y : R.concat(x, y)), {}),
R.map(([k, v]) => R.assocPath(R.split(/\.|:/, k), R.when(R.both(R.is(Object), R.compose(R.complement, R.is)(Array)), convertObjectStructure)(v), {})),
R.toPairs
)
// Usage
R.compose(
convertObjectStructure,
renameKeysDeep({'answer': {'null': 'PaymentsToIncuCode'}}),
R.dissocPath(['answer', 'paymentMethod:Paypal:PaypalUsageCode']),
)(JSON.parse(json))
中查看
我终于找到了解决问题的最佳方法。 Dot-Object 可以使用点符号转换 JavaScript 个对象。
var dot = require('dot-object');
var row = {
'id': 2,
'contact.name.first': 'John',
'contact.name.last': 'Doe',
'contact.email': 'example@gmail.com',
'contact.info.about.me': 'classified',
'devices[0]': 'mobile',
'devices[1]': 'laptop',
'some.other.things.0': 'this',
'some.other.things.1': 'that'
};
dot.object(row);
console.log(row);
// result will be as below
{
"id": 2,
"contact": {
"name": {
"first": "John",
"last": "Doe"
},
"email": "example@gmail.com",
"info": {
"about": {
"me": "classified"
}
}
},
"devices": [
"mobile",
"laptop"
],
"some": {
"other": {
"things": [
"this",
"that"
]
}
}
}
我有以下格式的对象。我在处理了一些数据之后得到了这个对象,并且密钥已经从上述数据中检索到了。这些键指的是一个数据结构,用“.”表示。句号。我正在寻找一种可以将此对象更改为第二个对象结构的方法,因为这样可以更轻松地将此数据保存在后端。
{
"pageId":"6103a64eaa0f0228d5487d8d",
"answer":{
"PremiumServices:AmazonPrime":"1",
"paymentMethod:Paypal:PaypalUsageCode":[
"2"
],
"PaymentsToIncurCode":[
"1",
"2"
],
"null":[
"10",
"4",
"7"
],
"paymentMethod:mobileWalletCodes":[
"10"
],
"paymentMethod:mobileWalletCodes.0":[
"17"
],
"paymentMethod:mobileWalletCodes.1":[
"17"
],
"paymentMethod:mobileWalletCodes.2":[
"16"
],
"paymentMethod:mobileWalletCodes.3":[
"16"
]
}
},
我想把它转换成下面的格式。
{
"pageId": "6103a64eaa0f0228d5487d8d",
"answer": {
"PremiumServices": {
"AmazonPrime": "1"
},
"paymentMethod": {
"mobileWalletCodes": {
"0": [
"17"
],
"1": [
"17"
],
"2": [
"16"
],
"3": [
"16"
]
}
},
"PaymentsToIncurCode": [
"1",
"2"
],
"PaymentsToIncuCode": [
"10",
"4",
"7"
]
}
}
是否有库或函数可以将第一个对象转换为第二个对象的格式?
属性有多个自定义转换步骤。这是我能够实现的最通用的方法:
const json = `{
"pageId":"6103a64eaa0f0228d5487d8d",
"answer":{
"PremiumServices:AmazonPrime":"1",
"paymentMethod:Paypal:PaypalUsageCode":[
"2"
],
"PaymentsToIncurCode":[
"1",
"2"
],
"null":[
"10",
"4",
"7"
],
"paymentMethod:mobileWalletCodes":[
"10"
],
"paymentMethod:mobileWalletCodes.0":[
"17"
],
"paymentMethod:mobileWalletCodes.1":[
"17"
],
"paymentMethod:mobileWalletCodes.2":[
"16"
],
"paymentMethod:mobileWalletCodes.3":[
"16"
]
}
}`;
const data = JSON.parse(json);
const result = {
pageId: data.pageId,
answer: {
PremiumServices: Object
.fromEntries(Object
.entries(data.answer)
.filter(([key]) =>
key.startsWith('PremiumServices')
).map(([key, value]) =>
[key.split(':')[1], value]
)
),
paymentMethod: Object
.fromEntries(Object
.entries(data.answer)
.filter(([key]) =>
key.startsWith('paymentMethod:mobileWalletCodes.')
).map(([key, value]) =>
[key.split('.')[1], value]
)
),
PaymentsToIncurCode: data.answer.PaymentsToIncurCode,
PaymentsToIncuCode: data.answer.null
}
};
console.log(result);
const resultJson = JSON.stringify(result);
console.log(resultJson);
.as-console-wrapper { min-height: 100%!important; top: 0; }
这是一个使用ramda
的函数式递归方法const convertObjectStructure = R.compose(
R.reduce(R.mergeDeepWith((x, y) => R.is(Object, x) && R.is(Array, y) ? x : R.is(Object, y) && R.is(Array, x) ? y : R.concat(x, y)), {}),
R.map(([k, v]) => R.assocPath(R.split(/\.|:/, k), R.when(R.both(R.is(Object), R.compose(R.complement, R.is)(Array)), convertObjectStructure)(v), {})),
R.toPairs
)
convertObjectStructure(JSON.parse(json))
没有我希望的那么干净,但是已经是午夜了。
中查看更新 #1
The output is not the sames as the OP's.. – Keith
const renameKeysDeep = R.curry((mapping, input) => R.compose(
R.reduce((acc, [k, v]) => {
if (!(k in mapping)) return {...acc, [k]: v};
if (R.is(Object)(mapping[k])) return {...acc, [k]: renameKeysDeep(mapping[k], v)};
return {...acc, [mapping[k]]: v};
}, {}),
R.toPairs
)(input))
const convertObjectStructure = R.compose(
R.reduce(R.mergeDeepWith((x, y) => R.is(Object, x) && R.is(Array, y) ? x : R.is(Object, y) && R.is(Array, x) ? y : R.concat(x, y)), {}),
R.map(([k, v]) => R.assocPath(R.split(/\.|:/, k), R.when(R.both(R.is(Object), R.compose(R.complement, R.is)(Array)), convertObjectStructure)(v), {})),
R.toPairs
)
// Usage
R.compose(
convertObjectStructure,
renameKeysDeep({'answer': {'null': 'PaymentsToIncuCode'}}),
R.dissocPath(['answer', 'paymentMethod:Paypal:PaypalUsageCode']),
)(JSON.parse(json))
中查看
我终于找到了解决问题的最佳方法。 Dot-Object 可以使用点符号转换 JavaScript 个对象。
var dot = require('dot-object');
var row = {
'id': 2,
'contact.name.first': 'John',
'contact.name.last': 'Doe',
'contact.email': 'example@gmail.com',
'contact.info.about.me': 'classified',
'devices[0]': 'mobile',
'devices[1]': 'laptop',
'some.other.things.0': 'this',
'some.other.things.1': 'that'
};
dot.object(row);
console.log(row);
// result will be as below
{
"id": 2,
"contact": {
"name": {
"first": "John",
"last": "Doe"
},
"email": "example@gmail.com",
"info": {
"about": {
"me": "classified"
}
}
},
"devices": [
"mobile",
"laptop"
],
"some": {
"other": {
"things": [
"this",
"that"
]
}
}
}