Node Js - 展平对象数组
Node Js - Flatten array of objects
我有一个这样的数组
var data = [
{
family: "Fam A",
category: "Cat A",
products: [
{
name: "Name A1",
style: "Style A1"
},
{
name: "Name A2",
style: "Style A2"
}
]
},
{
family: "Fam B",
category: "Cat B",
products: [
{
name: "Name B1",
style: "Style B1"
},
{
name: "Name B2",
style: "Style B2"
}
]
}
];
我想像下面这样更改内部对象
var data = [
{family:"Fam A", category: "Cat A", name: "Name A1", style:"Style A1"},
{family:"Fam A", category: "Cat A", name: "Name A2", style:"Style A2"},
{family:"Fam B", category: "Cat B", name: "Name B1", style:"Style B1"},
{family:"Fam B", category: "Cat B", name: "Name B2", style:"Style B2"}
]
我已经尝试使用我在其他帖子中找到的 map 和 forEach,但没有任何效果。
var flattened = data.products.map(x => Object.assign(x, { productDetails: data.products }))
function getList(data, arrayKey, arrayName) {
data[arrayKey].forEach(function(element) {
element[arrayName] = data[arrayName];
});
return data[arrayKey];
}
理想的解决方案将能够处理动态的嵌套数量,但没有必要继续前进。
提前感谢您帮助新开发者!
您可以使用嵌套映射 Array#flatMap
。
var data = [{ family: "Fam A", category: "Cat A", products: [{ name: "Name A1", style: "Style A1" }, { name: "Name A2", style: "Style A2" }] }, { family: "Fam B", category: "Cat B", products: [{ name: "Name B1", style: "Style B1" }, { name: "Name B2", style: "Style B2" }] }],
flat = data.flatMap(({ products, ...o }) => products.map(p => ({ ...o, ...p })));
console.log(flat);
.as-console-wrapper { max-height: 100% !important; top: 0; }
您可以使用reduce
,更快更好。
var data = [{"family":"Fam A","category":"Cat A","products":[{"name":"Name A1","style":"Style A1"},{"name":"Name A2","style":"Style A2"}]},{"family":"Fam B","category":"Cat B","products":[{"name":"Name B1","style":"Style B1"},{"name":"Name B2","style":"Style B2"}]}];
const result = data.reduce(
(map, { products, ...rest }) =>
map.concat(products.map(product => ({ ...rest, ...product }))),
[]
);
console.log(result);
我可以提供通用(递归)解决方案: recursion
var data = [
{
family: "Fam A",
category: "Cat A",
products: {
somekey: 'someval',
items : {
type: 'A type',
list: [{name: "Name A1", style: "Style A1"},
{name: "Name A2", style: "Style A2"}]
}
}
},
{
family: "Fam B",
category: "Cat B",
products: {
somekey: 'someval',
items :[{name: "Name B1", style: "Style B1"},
{name: "Name B2", style: "Style B2"}]
}
}
];
const output = data.reduce((aggArr, child) => {
function recursiveFlat(currChild, currParent){
currParent = currParent || {};
return Object.entries(currChild).reduce((aggChildArr,[key,val]) => {
let tempObj = {...currParent, ...currChild}
if (val instanceof Array){
delete tempObj[key];
val.forEach(item => {
aggChildArr.push({...tempObj,...item});
})
}else if(val instanceof Object){
delete tempObj[key];
aggChildArr = [...aggChildArr, ...recursiveFlat(val, tempObj)];
}
return aggChildArr;
},[])
}
const flatArr = recursiveFlat(child);
flatArr.forEach(item => aggArr.push(item));
return aggArr;
},[])
console.log(output);
.as-console-wrapper { max-height: 100% !important; top: 0; }
更新,尝试采用漂亮的 .flatMap()
解决方案并使其通用和递归:
const data = [{ family: "Fam A", category: "Cat A", items: { types: {type: 'A1-2', products: [{ name: "Name A1", style: "Style A1" }, { name: "Name A2", style: "Style A2" }]}, somekey: 'example' } }, { family: "Fam B", category: "Cat B", products: [{ name: "Name B1", style: "Style B1" }, { name: "Name B2", style: "Style B2" }] }];
function flatten(data){
const flat = data.flatMap((obj) => {
function innerFlatten(obj, parentObj){
parentObj = parentObj || {};
for (key in obj){
if (obj[key] instanceof Array){
const tempArr = obj[key];
delete obj[key];
return tempArr.map(p => ({...parentObj, ...obj, ...p }) )
}else if (obj[key] instanceof Object){
const tempObj = obj[key];
delete obj[key];
return innerFlatten(tempObj, {...parentObj, ...obj});
}
}
}
return innerFlatten(obj);
});
return flat;
}
console.log(flatten(data));
.as-console-wrapper { max-height: 100% !important; top: 0; }
我有一个这样的数组
var data = [
{
family: "Fam A",
category: "Cat A",
products: [
{
name: "Name A1",
style: "Style A1"
},
{
name: "Name A2",
style: "Style A2"
}
]
},
{
family: "Fam B",
category: "Cat B",
products: [
{
name: "Name B1",
style: "Style B1"
},
{
name: "Name B2",
style: "Style B2"
}
]
}
];
我想像下面这样更改内部对象
var data = [
{family:"Fam A", category: "Cat A", name: "Name A1", style:"Style A1"},
{family:"Fam A", category: "Cat A", name: "Name A2", style:"Style A2"},
{family:"Fam B", category: "Cat B", name: "Name B1", style:"Style B1"},
{family:"Fam B", category: "Cat B", name: "Name B2", style:"Style B2"}
]
我已经尝试使用我在其他帖子中找到的 map 和 forEach,但没有任何效果。
var flattened = data.products.map(x => Object.assign(x, { productDetails: data.products }))
function getList(data, arrayKey, arrayName) {
data[arrayKey].forEach(function(element) {
element[arrayName] = data[arrayName];
});
return data[arrayKey];
}
理想的解决方案将能够处理动态的嵌套数量,但没有必要继续前进。
提前感谢您帮助新开发者!
您可以使用嵌套映射 Array#flatMap
。
var data = [{ family: "Fam A", category: "Cat A", products: [{ name: "Name A1", style: "Style A1" }, { name: "Name A2", style: "Style A2" }] }, { family: "Fam B", category: "Cat B", products: [{ name: "Name B1", style: "Style B1" }, { name: "Name B2", style: "Style B2" }] }],
flat = data.flatMap(({ products, ...o }) => products.map(p => ({ ...o, ...p })));
console.log(flat);
.as-console-wrapper { max-height: 100% !important; top: 0; }
您可以使用reduce
,更快更好。
var data = [{"family":"Fam A","category":"Cat A","products":[{"name":"Name A1","style":"Style A1"},{"name":"Name A2","style":"Style A2"}]},{"family":"Fam B","category":"Cat B","products":[{"name":"Name B1","style":"Style B1"},{"name":"Name B2","style":"Style B2"}]}];
const result = data.reduce(
(map, { products, ...rest }) =>
map.concat(products.map(product => ({ ...rest, ...product }))),
[]
);
console.log(result);
我可以提供通用(递归)解决方案: recursion
var data = [
{
family: "Fam A",
category: "Cat A",
products: {
somekey: 'someval',
items : {
type: 'A type',
list: [{name: "Name A1", style: "Style A1"},
{name: "Name A2", style: "Style A2"}]
}
}
},
{
family: "Fam B",
category: "Cat B",
products: {
somekey: 'someval',
items :[{name: "Name B1", style: "Style B1"},
{name: "Name B2", style: "Style B2"}]
}
}
];
const output = data.reduce((aggArr, child) => {
function recursiveFlat(currChild, currParent){
currParent = currParent || {};
return Object.entries(currChild).reduce((aggChildArr,[key,val]) => {
let tempObj = {...currParent, ...currChild}
if (val instanceof Array){
delete tempObj[key];
val.forEach(item => {
aggChildArr.push({...tempObj,...item});
})
}else if(val instanceof Object){
delete tempObj[key];
aggChildArr = [...aggChildArr, ...recursiveFlat(val, tempObj)];
}
return aggChildArr;
},[])
}
const flatArr = recursiveFlat(child);
flatArr.forEach(item => aggArr.push(item));
return aggArr;
},[])
console.log(output);
.as-console-wrapper { max-height: 100% !important; top: 0; }
更新,尝试采用漂亮的 .flatMap()
解决方案并使其通用和递归:
const data = [{ family: "Fam A", category: "Cat A", items: { types: {type: 'A1-2', products: [{ name: "Name A1", style: "Style A1" }, { name: "Name A2", style: "Style A2" }]}, somekey: 'example' } }, { family: "Fam B", category: "Cat B", products: [{ name: "Name B1", style: "Style B1" }, { name: "Name B2", style: "Style B2" }] }];
function flatten(data){
const flat = data.flatMap((obj) => {
function innerFlatten(obj, parentObj){
parentObj = parentObj || {};
for (key in obj){
if (obj[key] instanceof Array){
const tempArr = obj[key];
delete obj[key];
return tempArr.map(p => ({...parentObj, ...obj, ...p }) )
}else if (obj[key] instanceof Object){
const tempObj = obj[key];
delete obj[key];
return innerFlatten(tempObj, {...parentObj, ...obj});
}
}
}
return innerFlatten(obj);
});
return flat;
}
console.log(flatten(data));
.as-console-wrapper { max-height: 100% !important; top: 0; }