在此处使用angularjs:
我有如下对象数组。在它下面只是显示2个对象的示例,但我可以超过2个。
[
{
"name": "John",
"control": "1",
"available": "true",
"comment": "n1",
"value": "v1"
},
{
"name": "Peter",
"control": "2",
"available": "true",
"type": "integer",
"comment": "n2",
"value": "v2",
"userOptions": [
{
"text": "Utah",
"value": "UT"
},
{
"text": "New York",
"value": "NY"
}
]
}
]
我想将json创建为:
"data":
{
"John":
{
"control": "1",
"features": {
"available": true
},
"value": "v1",
"comment": "c1"
} ,
"Peter":
{
"control": "2",
"features": {
"available": true,
"userOptions": {
"Utah": "UT",
"New York": "NY",
}
},
"value": "v2",
"comment": "c2"
}
}
因此,如果您看到json结构取决于控制键,则将添加一些额外的参数。 虽然某些键(如control,value,comment)保持不变。
任何人都可以分享如何创建上述json。我想在按钮事件中创建以上内容。
$scope.submit = function (isValid) {
if(isValid)
{
$scope.data.filter(function (item, index) {
for (var key in item) {
}
});
}
答案 0 :(得分:2)
x$1
答案 1 :(得分:1)
首先,您应注意,第一个结构支持具有相同名称的多个用户,而第二个结构(需要一个)不支持。无论如何,如果您可以确定名称是唯一的,Array.reduce()可能是您的选择。
const input = [{"name":"John","control":"1","available":"true","comment":"n1","value":"v1"},{"name":"Peter","control":"2","available":"true","type":"integer","comment":"n2","value":"v2","userOptions":[{"text":"Utah","value":"UT"},{"text":"New York","value":"NY"}]}];
let res = input.reduce((acc, user) =>
{
let {name, available, userOptions, ...others} = user;
acc[name] = {...others, features: {available: JSON.parse(available)}};
if (userOptions !== undefined)
{
acc[name].features.userOptions = {};
userOptions.forEach(({text, value}) =>
{
acc[name].features.userOptions[text] = value;
});
}
return acc;
}, {});
console.log(res);
.as-console {background-color:black !important; color:lime;}
.as-console-wrapper {max-height:100% !important; top:0;}
答案 2 :(得分:1)
我将从将其分解为较小的功能开始。我可能会得到这样的解决方案
const makeObject = kvs =>
kvs .reduce ( (a, {text, value} ) => ( {...a, [text]: value} ), {})
const makeFeatures = ( {available, userOptions: uo, ...rest} ) =>
( {...rest, features: {
...( available ? {available} : {}),
...( uo ? {userOptions: makeObject (uo) } : {} )
} } )
const transform = (people) =>
people.reduce( (a, {name, ...rest} ) => ( {...a, [name]: makeFeatures ({...rest}) }), {})
const people = [{"available": "true", "comment": "n1", "control": "1", "name": "John", "value": "v1"}, {"available": "true", "comment": "n2", "control": "2", "name": "Peter", "type": "integer", "userOptions": [{"text": "Utah", "value": "UT"}, {"text": "New York", "value": "NY"}], "value": "v2"}]
console .log (
transform (people)
)
.as-console {background-color:black !important; color:lime;}
.as-console-wrapper {max-height:100% !important; top:0;}
我将从外开始,首先像这样编写transform
版本:
const transform = (people) =>
people.reduce( (a, {name, ...rest} ) => ( {...a, [name]: {...rest} }), {})
只是将people
转换为
{
John: {...}
Peter: {...}
}
和那些内部对象具有name
以外的所有原始字段。
然后,我写一个makeFeatures
的版本,看起来像这样:
const makeFeatures = ( {available, ...rest} ) =>
( {...rest, features: {available} } )
这样makeFeatures(people[1])
会导致类似
{
comment: "n1",
control: "1",
features: {
available: "true"
},
value: "v1"
}
,对于people[2]
,它还将包括userOptions
和type
。
然后我可以像这样调整transform
:
const transform = (people) =>
people.reduce( (a, {name, ...rest} ) => ( {...a, [name]: makeFeatures({...rest}) }), {})
以便主函数将创建我们的基于名称的对象,并将available
提取到每个人的特征中。
现在available
在那,我们也需要处理userOptions
。这可能稍微复杂一点,因为可能包含也可能不包含。因此,我像这样更改makeFeatures
:
const makeFeatures = ( {available, userOptions, ...rest} ) =>
( {...rest, features: {available, ...( userOptions ? {userOptions} : {} )} } )
其中包括userOptions inside
个功能only if it's in the person object. Seeing this makes me wonder if
可用的`有时也可能包括在内,为了安全起见,我将这样重写:
const makeFeatures = ( {available, userOptions, ...rest} ) =>
( {...rest, features: {
...( available ? {available} : {}),
...( userOptions ? {userOptions} : {} )
} } )
因此,现在剩下要做的就是将userOptions
对象从[{text, value}, {text2, value2}, ...]
转换为{text: value, text2: value2, ...}
。我们为此编写了一个新函数:
const convertOptions = userOptions =>
userOptions .reduce ( (a, {text, value} ) => ( {...a, [text]: value} ), {})
,我们更改了makeFeatures来使用它:
const makeFeatures = ( {available, userOptions, ...rest} ) =>
( {...rest, features: {
...( available ? {available} : {}),
...( userOptions ? {userOptions: convertOptions (userOptions) } : {} )
} } )
我们现在有了工作代码。它符合目前为止我们所拥有的规格,并且很容易看出我们如何适应新的要求。
但是我仍然想进行两次清理。首先,makeFeatures
内对“ userOptions”的所有使用似乎都很混乱。我会添加这样的缩写:
const makeFeatures = ( {available, userOptions: uo, ...rest} ) =>
( {...rest, features: {
...( available ? {available} : {}),
...( uo ? {userOptions: convertOptions (uo) } : {} )
} } )
这是一个很小的考虑,有些人不赞成,但我觉得这样更容易。
第二,我们可以注意到convertOptions
与选项无关。这是一个通用函数,它接受text
/ value
对数组,并将它们转换为对象。因此,我将其重命名为makeObject
,并可能将其从此块移至某些实用程序代码。
虽然听起来很长且涉及很多,但所有这些步骤总共花费了不到10分钟的时间。我在REPL中运行了它,并获得了所做更改的即时反馈,而且实际上并不复杂。在这里写下来花费了更多时间。