英文:
Javascript consolidate iteration of objects
问题
我有一个动态对象myObj,如下所示:
{
"section-1": {
"id": "section-1",
"fields": [
{
"id": "field1",
"items": [
{
"display": "Select",
"value": "SELECT"
},
{
"display": "A 1",
"value": "A1"
},
{
"display": "A 2",
"value": "A2"
}
],
"value": "A1"
},
{
"id": "field2",
"items": [],
"value": "Field 2"
}
]
},
"section-2": {
"id": "section-2",
"fields": []
},
"section-3": {
"id": "section-3",
"fields": []
}
}
这些部分和字段都来自API响应,因此可以有n个部分和n个字段。
我想从这些对象中提取“myDefaults”,它是“value”属性。
到目前为止,我正在手动迭代每个部分,然后提取字段值到myDefaults,如下所示。
但是,我想知道是否可以以更好的方式编写这个逻辑(可能是ES6的方式),考虑到所有部分的结构都相似(只是可以有n个部分,其中包含n个字段)。
const section1 = myObj?.sections['section-1'];
const section2 = myObj?.sections['section-2'];
let myDefaults = {};
section1.fields.forEach((field) => {
myDefaults[field.id] = field.value;
if (field.items && field.items.length > 0) {
myDefaults[field.id] = field.items.find(item => item.value === field.value);
}
});
section2.fields.forEach((field) => {
myDefaults[field.id] = field.value;
if (field.items && field.items.length > 0) {
myDefaults[field.id] = field.items.find(item => item.value === field.value);
}
});
英文:
I have a dynamic object myObj as below
{
"section-1": {
"id": "section-1",
"fields": [
{
"id": "field1",
"items": [
{
"display": "Select",
"value": "SELECT"
},
{
"display": "A 1",
"value": "A1"
},
{
"display": "A 2",
"value": "A2"
}
],
"value": "A1"
}, {
"id": "field2",
"items": [],
"value": "Field 2"
}
]
},
"section-2": {
"id": "section-2",
"fields": []
},
section-3": {
"id": "section-3",
"fields": []
}
}
The sections and fields are both dynamic from API response. So, it can have n number of sections and n number of fields.
I want to extract "myDefaults" from within these objects which is the "value" attribute.
As of now, I am manually iterating through each section and then extracting field.value into myDefaults as below.
However, I am wondering if there can be any better way of writing this logic (probably ES6 way of writing), considering all the sections would have similar structure (just that there can be n number of sections with n number of fields within them)
const section1 = myObj?.sections['section-1'];
const section2 = myObj?.sections['section-2'];
let myDefaults = {};
section1.fields.forEach((field) => {
myDefaults[field.id] = field.value;
if (field.items && field.items.length > 0) {
myDefaults[field.id] = field.items.find(item => item.value === field.value);
}
});
section2.fields.forEach((field) => {
myDefaults[field.id] = field.value;
if (field.items && field.items.length > 0) {
myDefaults[field.id] = field.items.find(item => item.value === field.value);
}
});
答案1
得分: 3
你可以使用 Object.values
来避免硬编码部分名称。
此代码获取所有部分,然后对每个部分的字段进行访问。它在项目列表中查找所选值。是否找到匹配项决定了我们是只使用该值还是一个包含值和显示属性的对象。
最后,我们使用 Object.fromEntries
将所有 [key, value]
条目合并为一个单一对象。
英文:
You can use Object.values
to avoid hard-coding the section names.
This code gets all sections, then for each section visits each field. It looks up the selected value in the list of items. Whether a match is found determines whether we just use the value or an object containing the value and the display property.
Finally, we use Object.fromEntries
to merge all of the [key, value]
entries into a single object.
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-js -->
const myObj = {"sections":{"section-1":{"id":"section-1","fields":[{"id":"field1","items":[{"display":"Select","value":"SELECT"},{"display":"A 1","value":"A1"},{"display":"A 2","value":"A2"}],"value":"A1"},{"id":"field2","items":[],"value":"Field 2"}]},"section-2":{"id":"section-2","fields":[]},"section-3":{"id":"section-3","fields":[]}}};
console.log(
Object.fromEntries(Object.values(myObj.sections)
.flatMap(i => i.fields.map(({id, items, value}) => [
id,
items?.find(item => item.value===value) ?? value
]))
)
)
<!-- end snippet -->
答案2
得分: 1
这适用于您在示例中提供的对象。您可以编辑它以适应您的业务需求。干杯!
Object.keys(myObj)
.map(key => myObj[key].fields)
.flat()
.reduce((result, fieldItem) => {
const { id, items, value } = fieldItem;
result[id] = items?.length ?
items.find(i => i.value == value)
: value;
return result;
}, {})
P.S. 我还没有考虑到任何边缘情况 xD
英文:
This works for the object that you gave in the example. You can edit it to suit your business needs. Cheers!
Object.keys(myObj)
.map(key=> myObj[key].fields)
.flat()
.reduce((result, fieldItem)=>{
const {id, items, value } = fieldItem
result[id] = items?.length ?
items.find(i => i.value == value)
: value;
return result;
}, {})
P.S. I haven't thought of any edge cases though xD
答案3
得分: 1
I have used your logic but used it in combination with Object.entries
and Array#reduce
:
let myObj = {
sections: {
"section-1": {
id: "section-1",
fields: [
{
id: "field1",
items: [
{ display: "Select", value: "SELECT" },
{ display: "A 1", value: "A1" },
{ display: "A 2", value: "A2" }
],
value: "A1"
},
{
id: "field2",
items: [],
value: "Field 2"
}
],
value: "A1"
},
"section-2": {
id: "section-2",
fields: []
},
"section-3": {
id: "section-3",
fields: []
}
}
};
let result = Object.entries(myObj.sections).reduce((acc, [keys, values]) => {
values.fields.forEach((field) => {
acc[field.id] = field.value;
if (field.items && field.items.length > 0) {
acc[field.id] = field.items.find(item => item.value === field.value);
}
});
return acc;
}, {});
console.log(result);
英文:
I have used your logic but used it in combination with Object.entries
and Array#reduce
:
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-js -->
let myObj={sections:{"section-1":{id:"section-1",fields:[{id:"field1",items:[{display:"Select",value:"SELECT"},{display:"A 1",value:"A1"},{display:"A 2",value:"A2"}],value:"A1"},{id:"field2",items:[],value:"Field 2"}]},"section-2":{id:"section-2",fields:[]},"section-3":{id:"section-3",fields:[]}}};
let result = Object.entries(myObj.sections).reduce((acc, [keys, values]) => {
values.fields.forEach((field) => {
acc[field.id] = field.value;
if (field.items && field.items.length > 0) {
acc[field.id] = field.items.find(item => item.value === field.value);
}
});
return acc
}, {})
console.log(result)
<!-- end snippet -->
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论