过滤和重组对象数组
Filtering and restructuring array of objects
我得到的是对象数组
const incomeRows = [
{
group: "Deck 1",
categories: [
{ category: "Deck Supplies", reportvalue: 100, transdate: "2020-11" },
{ category: "Deck Supplies", reportvalue: 200, transdate: "2020-11" },
{ category: "Deck Contractors", reportvalue: 300, transdate: "2020-11" },
{ category: "Deck Contractors", reportvalue: 400, transdate: "2020-12" },
{ category: "Deck Contractors", reportvalue: 500, transdate: "2020-12" }
]
},
{
group: "Deck 2",
categories: [
{ category: "Deck Supplies", reportvalue: 10, transdate: "2020-11" },
{ category: "Deck Supplies", reportvalue: 20, transdate: "2020-11" },
{ category: "Deck Contractors", reportvalue: 30, transdate: "2020-11" },
{ category: "Deck Contractors", reportvalue: 40, transdate: "2020-12" },
{ category: "Deck Contractors", reportvalue: 50, transdate: "2020-12" }
]
}
];
我需要创建的是:
const finalOutput = [
{
group: "Deck 1",
categories: [
{
category: "Deck Supplies",
"2020-11": 300
},
{
category: "Deck Contractors",
"2020-11": 300,
"2020-12": 900
}
],
groupMonthlyIncomes: {
"2020-11": 600,
"2020-12": 900
}
},
{
group: "Deck 2",
categories: [
{
category: "Deck Supplies",
"2020-11": 30
},
{
category: "Deck Contractors",
"2020-11": 30,
"2020-12": 90
}
],
groupMonthlyIncomes: {
"2020-11": 60,
"2020-12": 90
}
}
];
因此该类别是唯一的,并且每个月都有总值,例如 "2020-11": 300
每个组都有其每月总值,如
groupMonthlyIncomes: {
"2020-11": 60,
"2020-12": 90
}
到目前为止我所做的是:
let formatedRows = incomeRows.map(el => (
{
group: el.group,
categories: []
}
));
let formatedCategories = incomeRows.map(el => (
el.categories.map(cat => {
return {
category: cat.category,
[cat.transdate.toString()]: cat.reportvalue
}
})
));
任何人都可以让我知道下一步应该是什么,或者如果有更好的方法可以指出任何其他解决方案吗?
试试这个:
incomeRows.map((row) => {
return {
group: row.group,
categories: row.categories.map((cat) => {
return {
category: cat.category,
[cat.transdate]: cat.reportvalue,
}
}),
groupMonthlyIncomes: row.categories.reduce((result, next) => {
const key = next.transdate;
result[key] = result[key] ? result[key] + next.reportvalue : next.reportvalue;
return result;
}, {}),
}
});
const reorganization = () => {
// declares an array of property names
const attrs = ['category', 'transdate', 'reportvalue', 'categories', 'groupMonthlyIncomes'];
return incomeRows.map(row => {
// do something for categories
const categorieMap = new Map([...new Map(row.categories.map(item => [item[attrs[0]], new Map()]))]);
const categories = [...categorieMap.keys()];
for (let i = 0; i < categories.length; i++) {
const _map = categorieMap.get(categories[i]);
for (let j = 0; j < row.categories.length; j++) {
if (row.categories[j][attrs[0]] == categories[i]) {
const _mapKey = row.categories[j][attrs[1]];
const _mapVal = row.categories[j][attrs[2]];
_map.set(_mapKey, _map.has(_mapKey) ? _map.get(_mapKey) + _mapVal : _mapVal);
}
}
_map.set(attrs[0], categories[i]);
categories[i] = Object.fromEntries([..._map].map(
m => m.flat()).map(a => ({
[a[0]]: a[1]
})).flatMap(Object.entries));
}
row[attrs[3]] = categories;
// do something for groupMonthlyIncomes
let groupMonthlyIncomes = new Map();
for (let i = 0; i < categories.length; i++) {
const categorie = categories[i];
delete categorie[attrs[0]];
for (const [key, value] of Object.entries(categories[i])) {
groupMonthlyIncomes.set(key, groupMonthlyIncomes.has(key) ? groupMonthlyIncomes.get(key) + value : value);
}
}
row[attrs[4]] = Object.fromEntries([...groupMonthlyIncomes].map(
m => m.flat()).map(a => ({
[a[0]]: a[1]
})).flatMap(Object.entries));
return row;
});
}
const incomeRows = [{
group: "Deck 1",
categories: [{
category: "Deck Supplies",
reportvalue: 100,
transdate: "2020-11"
},
{
category: "Deck Supplies",
reportvalue: 200,
transdate: "2020-11"
},
{
category: "Deck Contractors",
reportvalue: 300,
transdate: "2020-11"
},
{
category: "Deck Contractors",
reportvalue: 400,
transdate: "2020-12"
},
{
category: "Deck Contractors",
reportvalue: 500,
transdate: "2020-12"
}
]
},
{
group: "Deck 2",
categories: [{
category: "Deck Supplies",
reportvalue: 10,
transdate: "2020-11"
},
{
category: "Deck Supplies",
reportvalue: 20,
transdate: "2020-11"
},
{
category: "Deck Contractors",
reportvalue: 30,
transdate: "2020-11"
},
{
category: "Deck Contractors",
reportvalue: 40,
transdate: "2020-12"
},
{
category: "Deck Contractors",
reportvalue: 50,
transdate: "2020-12"
}
]
}
];
console.log(reorganization());
试试这个:
incomeRows.map((row) => {
const reportValues = row.categories.reduce((result, next) => {
const catKey = next.category;
const total = row.categories.
filter((_cat) => _cat.category === next.category && _cat.transdate === next.transdate)
.reduce((accum, _next) => accum + _next.reportvalue, 0);
result[catKey] = result[catKey] ? {...result[catKey], [next.transdate]: total} : {[next.transdate]: total};
return result;
}, {});
return {
group: row.group,
categories: Object.keys(reportValues).map((_key) => {
return {
category: _key,
...reportValues[_key],
}
}),
groupMonthlyIncomes: row.categories.reduce((result, next) => {
const key = next.transdate;
result[key] = result[key] ? result[key] + next.reportvalue : next.reportvalue;
return result;
}, {}),
}
});
我得到的是对象数组
const incomeRows = [
{
group: "Deck 1",
categories: [
{ category: "Deck Supplies", reportvalue: 100, transdate: "2020-11" },
{ category: "Deck Supplies", reportvalue: 200, transdate: "2020-11" },
{ category: "Deck Contractors", reportvalue: 300, transdate: "2020-11" },
{ category: "Deck Contractors", reportvalue: 400, transdate: "2020-12" },
{ category: "Deck Contractors", reportvalue: 500, transdate: "2020-12" }
]
},
{
group: "Deck 2",
categories: [
{ category: "Deck Supplies", reportvalue: 10, transdate: "2020-11" },
{ category: "Deck Supplies", reportvalue: 20, transdate: "2020-11" },
{ category: "Deck Contractors", reportvalue: 30, transdate: "2020-11" },
{ category: "Deck Contractors", reportvalue: 40, transdate: "2020-12" },
{ category: "Deck Contractors", reportvalue: 50, transdate: "2020-12" }
]
}
];
我需要创建的是:
const finalOutput = [
{
group: "Deck 1",
categories: [
{
category: "Deck Supplies",
"2020-11": 300
},
{
category: "Deck Contractors",
"2020-11": 300,
"2020-12": 900
}
],
groupMonthlyIncomes: {
"2020-11": 600,
"2020-12": 900
}
},
{
group: "Deck 2",
categories: [
{
category: "Deck Supplies",
"2020-11": 30
},
{
category: "Deck Contractors",
"2020-11": 30,
"2020-12": 90
}
],
groupMonthlyIncomes: {
"2020-11": 60,
"2020-12": 90
}
}
];
因此该类别是唯一的,并且每个月都有总值,例如 "2020-11": 300
每个组都有其每月总值,如
groupMonthlyIncomes: {
"2020-11": 60,
"2020-12": 90
}
到目前为止我所做的是:
let formatedRows = incomeRows.map(el => (
{
group: el.group,
categories: []
}
));
let formatedCategories = incomeRows.map(el => (
el.categories.map(cat => {
return {
category: cat.category,
[cat.transdate.toString()]: cat.reportvalue
}
})
));
任何人都可以让我知道下一步应该是什么,或者如果有更好的方法可以指出任何其他解决方案吗?
试试这个:
incomeRows.map((row) => {
return {
group: row.group,
categories: row.categories.map((cat) => {
return {
category: cat.category,
[cat.transdate]: cat.reportvalue,
}
}),
groupMonthlyIncomes: row.categories.reduce((result, next) => {
const key = next.transdate;
result[key] = result[key] ? result[key] + next.reportvalue : next.reportvalue;
return result;
}, {}),
}
});
const reorganization = () => {
// declares an array of property names
const attrs = ['category', 'transdate', 'reportvalue', 'categories', 'groupMonthlyIncomes'];
return incomeRows.map(row => {
// do something for categories
const categorieMap = new Map([...new Map(row.categories.map(item => [item[attrs[0]], new Map()]))]);
const categories = [...categorieMap.keys()];
for (let i = 0; i < categories.length; i++) {
const _map = categorieMap.get(categories[i]);
for (let j = 0; j < row.categories.length; j++) {
if (row.categories[j][attrs[0]] == categories[i]) {
const _mapKey = row.categories[j][attrs[1]];
const _mapVal = row.categories[j][attrs[2]];
_map.set(_mapKey, _map.has(_mapKey) ? _map.get(_mapKey) + _mapVal : _mapVal);
}
}
_map.set(attrs[0], categories[i]);
categories[i] = Object.fromEntries([..._map].map(
m => m.flat()).map(a => ({
[a[0]]: a[1]
})).flatMap(Object.entries));
}
row[attrs[3]] = categories;
// do something for groupMonthlyIncomes
let groupMonthlyIncomes = new Map();
for (let i = 0; i < categories.length; i++) {
const categorie = categories[i];
delete categorie[attrs[0]];
for (const [key, value] of Object.entries(categories[i])) {
groupMonthlyIncomes.set(key, groupMonthlyIncomes.has(key) ? groupMonthlyIncomes.get(key) + value : value);
}
}
row[attrs[4]] = Object.fromEntries([...groupMonthlyIncomes].map(
m => m.flat()).map(a => ({
[a[0]]: a[1]
})).flatMap(Object.entries));
return row;
});
}
const incomeRows = [{
group: "Deck 1",
categories: [{
category: "Deck Supplies",
reportvalue: 100,
transdate: "2020-11"
},
{
category: "Deck Supplies",
reportvalue: 200,
transdate: "2020-11"
},
{
category: "Deck Contractors",
reportvalue: 300,
transdate: "2020-11"
},
{
category: "Deck Contractors",
reportvalue: 400,
transdate: "2020-12"
},
{
category: "Deck Contractors",
reportvalue: 500,
transdate: "2020-12"
}
]
},
{
group: "Deck 2",
categories: [{
category: "Deck Supplies",
reportvalue: 10,
transdate: "2020-11"
},
{
category: "Deck Supplies",
reportvalue: 20,
transdate: "2020-11"
},
{
category: "Deck Contractors",
reportvalue: 30,
transdate: "2020-11"
},
{
category: "Deck Contractors",
reportvalue: 40,
transdate: "2020-12"
},
{
category: "Deck Contractors",
reportvalue: 50,
transdate: "2020-12"
}
]
}
];
console.log(reorganization());
试试这个:
incomeRows.map((row) => {
const reportValues = row.categories.reduce((result, next) => {
const catKey = next.category;
const total = row.categories.
filter((_cat) => _cat.category === next.category && _cat.transdate === next.transdate)
.reduce((accum, _next) => accum + _next.reportvalue, 0);
result[catKey] = result[catKey] ? {...result[catKey], [next.transdate]: total} : {[next.transdate]: total};
return result;
}, {});
return {
group: row.group,
categories: Object.keys(reportValues).map((_key) => {
return {
category: _key,
...reportValues[_key],
}
}),
groupMonthlyIncomes: row.categories.reduce((result, next) => {
const key = next.transdate;
result[key] = result[key] ? result[key] + next.reportvalue : next.reportvalue;
return result;
}, {}),
}
});