我正在尝试搜索对象中的特定节点,并显示包含所需数据的新对象。每种复合类型中可能有单个或多个字段,如下所示。
这是原始对象:
{
"section": "personal",
"fields": [
{
"type": "composite",
"name": "name",
"label": "Name",
"fields": [
{
"type": "text",
"name": "given",
"label": "First name",
"value": "Joe"
},
{
"type": "text",
"name": "family",
"label": "Last name",
"value": "Smith"
}
]
},
{
"type": "composite",
"name": "address",
"label": "Address",
"fields": [
{
"type": "text",
"name": "streetName",
"label": "Street Name",
"value": "1 High St"
},
{
"type": "text",
"name": "city",
"label": "City",
"value": "New York"
}
]
}
]
}
生成的对象应如下所示:
{
name: {
given: "Joe",
family: "Smith",
},
address: {
streetName: "1 Hight St",
city: "New York"
}
}
编辑***理想情况下,我想找出一种方法来使用javascript方法(map / reduce / filter)和/或lodash来提出答案。
这更像是我目前使用内置方法所看到的内容。
var convertVals = function() {
var data = fields.fields;
var filter = data.filter(function(form) {
return form
})
.filter(function(form) {
return form.name && form.fields;
})
.map(function(form) {
return {form.name, [form.name.name]: form.name.value};
})
};
convertVals();

谢谢,
答案 0 :(得分:1)
好的,你走吧!想象一下,我不妨对它进行抨击,因为没有更多的问题进入。
var originalObject = {
"section": "personal",
"fields": [
{
"type": "composite",
"name": "name",
"label": "Name",
"fields": [
{
"type": "text",
"name": "given",
"label": "First name",
"value": "Joe"
},
{
"type": "text",
"name": "family",
"label": "Last name",
"value": "Smith"
}
]
},
{
"type": "composite",
"name": "address",
"label": "Address",
"fields": [
{
"type": "text",
"name": "streetName",
"label": "Street Name",
"value": "1 High St"
},
{
"type": "text",
"name": "city",
"label": "City",
"value": "New York"
}
]
}
]
};
function convertVals(obj){
var retObj = {};
for(var i=0;i<obj.fields.length;i++){
var tempObj={};
for(var j=0;j<obj.fields[i].fields.length;j++){
tempObj[obj.fields[i].fields[j].name] = obj.fields[i].fields[j].value;
}
retObj[obj.fields[i].name] = tempObj;
}
return retObj;
}
console.log(convertVals(originalObject));
/*
Should return:
{
name: {
given: "Joe",
family: "Smith",
},
address: {
streetName: "1 Hight St",
city: "New York"
}
}
*/
答案 1 :(得分:1)
这是一个使用keyBy为每个字段分配密钥的lodash解决方案,mapValues为每个字段获取值。
function getFields(data) {
return data.value || _(data.fields)
.keyBy('name')
.mapValues(getFields)
.value();
}
var data = {
"section": "personal",
"fields": [{
"type": "composite",
"name": "name",
"label": "Name",
"fields": [{
"type": "text",
"name": "given",
"label": "First name",
"value": "Joe"
},
{
"type": "text",
"name": "family",
"label": "Last name",
"value": "Smith"
}
]
},
{
"type": "composite",
"name": "address",
"label": "Address",
"fields": [{
"type": "text",
"name": "streetName",
"label": "Street Name",
"value": "1 High St"
},
{
"type": "text",
"name": "city",
"label": "City",
"value": "New York"
}
]
}
]
};
function getFields(data) {
return data.value || _(data.fields)
.keyBy('name')
.mapValues(getFields)
.value();
}
console.log(getFields(data));
body > div { min-height: 100%; top: 0; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.js"></script>
上述解决方案存在隐含的含义,如果value
包含假值,则会忽略此value
并假设有fields
值。要解决此问题,我们可以使用has检查是否存在value
密钥,然后执行与上面相同的操作。
function getFields(data) {
return _.has(data, 'value')? data.value:
_(data.fields)
.keyBy('name')
.mapValues(getFields)
.value();
}
var data = {
"section": "personal",
"fields": [{
"type": "composite",
"name": "name",
"label": "Name",
"fields": [{
"type": "text",
"name": "given",
"label": "First name",
"value": "Joe"
},
{
"type": "text",
"name": "family",
"label": "Last name",
"value": "Smith"
}
]
},
{
"type": "composite",
"name": "address",
"label": "Address",
"fields": [{
"type": "text",
"name": "streetName",
"label": "Street Name",
"value": "1 High St"
},
{
"type": "text",
"name": "city",
"label": "City",
"value": "New York"
}
]
}
]
};
function getFields(data) {
return _.has(data, 'value')? data.value:
_(data.fields)
.keyBy('name')
.mapValues(getFields)
.value();
}
console.log(getFields(data));
body > div { min-height: 100%; top: 0; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.js"></script>
答案 2 :(得分:1)
您可以使用Array.prototype.reduce()
来迭代嵌套的fields
数组。将父对象的"name"
属性值设置为对象的属性名称,其值设置为对象设置为"name"
,并且"value"
数组中的对象属性为"fields"
var data = {
"section": "personal",
"fields": [
{
"type": "composite",
"name": "name",
"label": "Name",
"fields": [
{
"type": "text",
"name": "given",
"label": "First name",
"value": "Joe"
},
{
"type": "text",
"name": "family",
"label": "Last name",
"value": "Smith"
}
]
},
{
"type": "composite",
"name": "address",
"label": "Address",
"fields": [
{
"type": "text",
"name": "streetName",
"label": "Street Name",
"value": "1 High St"
},
{
"type": "text",
"name": "city",
"label": "City",
"value": "New York"
}
]
}
]
}
var res = data.fields.reduce((o, {name, fields}) =>
(o[name] = fields.reduce((curr, {name:key, value}) =>
(curr[key] = value, curr),{}), o), {});
console.log(res);