使用对象数组的对象中的唯一元素创建新对象
Create new object with unique elements from objects of array of objects
我有一个对象数组。这个数组中的每个对象都有一些密钥对。其中一个密钥对(例如“obj”)也是一个对象数组。
举个例子:
const arrOfObj = [
{
"id": 1
"obj": {
"arr1": ["arr1-1"],
"arr2": ["arr2-1", "arr2-2"],
"arr3": ["arr3-1", "arr3-2"]
}
},
{
"id": 1
"obj": {
"arr1": ["arr1-2"],
"arr2": ["arr2-1", "arr2-3"],
"arr3": ["arr3-1", "arr3-3"],
"arr4": ["arr4-1"],
}
},
];
我需要获取“obj”对象的新对象,其中包含唯一键和唯一元素。
我需要的示例:
const newObj = {
"arr1": ["arr1-1", "arr1-2"],
"arr2": ["arr2-1", "arr2-2", "arr2-3"],
"arr3": ["arr3-1", "arr3-2", "arr3-3"],
"arr4": ["arr4-1"],
}
所有这些都根据请求动态地来自 API,所以我不知道这个密钥对的名称,但我需要存储它们。
我有解决方案,但我是JavaScript的新手,想知道如何简化和改进我糟糕的代码.
1. 首先,我正在定义新对象并从“arrOfObj”中检索其密钥对的名称。
let filterObj = {};
arrOfObj.forEach(function (item) {
for (let key in item.obj) {
filterObj[key] = [];
}
});
2. 之后,我从“arrOfObj”获取每个数组的所有元素,并将它们存储在具有相同名称的密钥对中的新对象“filterObj”中。
arrOfObj.forEach(function (item) {
for (let key in item.obj) {
for (let element = 0; element < item.obj[key].length; element++) {
filterObj[key].push(item.obj[key][element]);
}
}
});
3. 最后,我过滤数组以仅获取唯一元素。
for (let key in filterObj) {
filterObj[key] = Array.from(new Set(filterObj[key]));
}
它有效,我得到了我想要的东西,但它看起来太可怕了。如何以最佳方式简化此代码?
感谢您的帮助和建议。
另一种使用 Object#fromEntries
, Array#reduce
, Object#entries
, Array#forEach
, Set
, and Map
的解决方案:
const arrOfObj = [ { "id": 1, "obj": { "arr1": ["arr1-1"], "arr2": ["arr2-1", "arr2-2"], "arr3": ["arr3-1", "arr3-2"] } }, { "id": 1, "obj": { "arr1": ["arr1-2"], "arr2": ["arr2-1", "arr2-3"], "arr3": ["arr3-1", "arr3-3"], "arr4": ["arr4-1"] } } ];
const filterObj =
// transform the resulting list of key-values pairs to an object at the end
Object.fromEntries(
// get a map of array name as key and its unique items as value
[...arrOfObj.reduce((map, { obj = {} }) => {
// iterate over current element's object to update the map
Object.entries(obj).forEach(([currentKey, currentValues]) => {
const keyValues = [...(map.get(currentKey) || []), ...currentValues];
map.set(currentKey, [...new Set(keyValues)]);
});
return map;
}, new Map)]
);
console.log(filterObj);
您可以使用一些解构以及 Object.entries() 和 Object.keys() 来简化此操作并仅对新对象执行所有操作
const newObj = {}
arrOfObj.forEach(({obj}) => {
Object.entries(obj).forEach(([k, arr]) => {
newObj[k] = newObj[k] || [];
newObj[k].push(...arr);
})
});
Object.keys(newObj).forEach(k => newObj[k] = [...new Set(newObj[k])]);
console.log(newObj)
<script>
const arrOfObj=[{id:1,obj:{arr1:["arr1-1"],arr2:["arr2-1","arr2-2"],arr3:["arr3-1","arr3-2"]}},{id:1,obj:{arr1:["arr1-2"],arr2:["arr2-1","arr2-3"],arr3:["arr3-1","arr3-3"],arr4:["arr4-1"]}}];
</script>
我有一个对象数组。这个数组中的每个对象都有一些密钥对。其中一个密钥对(例如“obj”)也是一个对象数组。
举个例子:
const arrOfObj = [
{
"id": 1
"obj": {
"arr1": ["arr1-1"],
"arr2": ["arr2-1", "arr2-2"],
"arr3": ["arr3-1", "arr3-2"]
}
},
{
"id": 1
"obj": {
"arr1": ["arr1-2"],
"arr2": ["arr2-1", "arr2-3"],
"arr3": ["arr3-1", "arr3-3"],
"arr4": ["arr4-1"],
}
},
];
我需要获取“obj”对象的新对象,其中包含唯一键和唯一元素。
我需要的示例:
const newObj = {
"arr1": ["arr1-1", "arr1-2"],
"arr2": ["arr2-1", "arr2-2", "arr2-3"],
"arr3": ["arr3-1", "arr3-2", "arr3-3"],
"arr4": ["arr4-1"],
}
所有这些都根据请求动态地来自 API,所以我不知道这个密钥对的名称,但我需要存储它们。
我有解决方案,但我是JavaScript的新手,想知道如何简化和改进我糟糕的代码.
1. 首先,我正在定义新对象并从“arrOfObj”中检索其密钥对的名称。
let filterObj = {};
arrOfObj.forEach(function (item) {
for (let key in item.obj) {
filterObj[key] = [];
}
});
2. 之后,我从“arrOfObj”获取每个数组的所有元素,并将它们存储在具有相同名称的密钥对中的新对象“filterObj”中。
arrOfObj.forEach(function (item) {
for (let key in item.obj) {
for (let element = 0; element < item.obj[key].length; element++) {
filterObj[key].push(item.obj[key][element]);
}
}
});
3. 最后,我过滤数组以仅获取唯一元素。
for (let key in filterObj) {
filterObj[key] = Array.from(new Set(filterObj[key]));
}
它有效,我得到了我想要的东西,但它看起来太可怕了。如何以最佳方式简化此代码?
感谢您的帮助和建议。
另一种使用 Object#fromEntries
, Array#reduce
, Object#entries
, Array#forEach
, Set
, and Map
的解决方案:
const arrOfObj = [ { "id": 1, "obj": { "arr1": ["arr1-1"], "arr2": ["arr2-1", "arr2-2"], "arr3": ["arr3-1", "arr3-2"] } }, { "id": 1, "obj": { "arr1": ["arr1-2"], "arr2": ["arr2-1", "arr2-3"], "arr3": ["arr3-1", "arr3-3"], "arr4": ["arr4-1"] } } ];
const filterObj =
// transform the resulting list of key-values pairs to an object at the end
Object.fromEntries(
// get a map of array name as key and its unique items as value
[...arrOfObj.reduce((map, { obj = {} }) => {
// iterate over current element's object to update the map
Object.entries(obj).forEach(([currentKey, currentValues]) => {
const keyValues = [...(map.get(currentKey) || []), ...currentValues];
map.set(currentKey, [...new Set(keyValues)]);
});
return map;
}, new Map)]
);
console.log(filterObj);
您可以使用一些解构以及 Object.entries() 和 Object.keys() 来简化此操作并仅对新对象执行所有操作
const newObj = {}
arrOfObj.forEach(({obj}) => {
Object.entries(obj).forEach(([k, arr]) => {
newObj[k] = newObj[k] || [];
newObj[k].push(...arr);
})
});
Object.keys(newObj).forEach(k => newObj[k] = [...new Set(newObj[k])]);
console.log(newObj)
<script>
const arrOfObj=[{id:1,obj:{arr1:["arr1-1"],arr2:["arr2-1","arr2-2"],arr3:["arr3-1","arr3-2"]}},{id:1,obj:{arr1:["arr1-2"],arr2:["arr2-1","arr2-3"],arr3:["arr3-1","arr3-3"],arr4:["arr4-1"]}}];
</script>