如何从现有条目创建新对象?
How to create a new object from existing entries?
我正在尝试创建一个对象,该对象将填充现有对象的值。在我的例子中,它应该根据“Material”得到一个包含“代码”和“数量”的对象列表。另外,如果“Material”和“Code”相同,则“Quantity”要相加。
我希望你能从我的例子中明白我的意思。谢谢
const arr = [{
"Material": "123",
"Code": "AAA",
"Quantity": 1
}, {
"Material": "123",
"Code": "BBB",
"Quantity": 2
}, {
"Material": "123",
"Code": "BBB",
"Quantity": 2
}, {
"Material": "456",
"Code": "CCC",
"Quantity": 7
}]
var arrResult = [{
"Material": "123",
"CodeQuantity": [{
"Code": "AAA",
"Quantity": 1
}, {
"Code": "BBB",
"Quantity": 4
}]
}, {
"Material": "456",
"CodeQuantity": [{
"Code": "CCC",
"Quantity": 7
}]
}]
console.log(arr)
console.log("Result:", arrResult)
试试这个
const arr = [{
"Material": "123",
"Code": "AAA",
"Quantity": 1
}, {
"Material": "123",
"Code": "BBB",
"Quantity": 2
}, {
"Material": "123",
"Code": "BBB",
"Quantity": 2
}, {
"Material": "456",
"Code": "CCC",
"Quantity": 7
}];
let group = arr.reduce((r, a) => {
r[a.Material] = [...r[a.Material] || [], a];
return r;
}, {});
var newArr = Object.keys(group).map(key => {
var elem = group[key];
var b = elem.map(e => {
return {
Code: e.Code,
Quantity: e.Quantity
}
});
var filteredArr = [];
b.map(i => {
var item = filteredArr.find(n => n.Code == i.Code);
if (item) {
item.Quantity += i.Quantity;
} else {
filteredArr.push(i);
}
})
return {
Material: key,
CodeQuantity: filteredArr
}
});
console.log(newArr);
更新了解决方案以符合您的期望。
这这。希望它能解决您的用例。
const arr = [{
"Material": "123",
"Code": "AAA",
"Quantity": 1
}, {
"Material": "123",
"Code": "BBB",
"Quantity": 2
}, {
"Material": "123",
"Code": "BBB",
"Quantity": 2
}, {
"Material": "456",
"Code": "CCC",
"Quantity": 7
}]
var arrResultExpected = [{
"Material": "123",
"CodeQuantity": [{
"Code": "AAA",
"Quantity": 1
}, {
"Code": "BBB",
"Quantity": 4
}]
}, {
"Material": "456",
"CodeQuantity": [{
"Code": "CCC",
"Quantity": 7
}]
}]
//console.log(arr)
//console.log("ExpecredResult:", arrResultExpected)
const materialIds = arr.map(a => a.Material);
//console.log(materialIds);
const dedupedMaterialIds = [...new Set(materialIds)]
//console.log(dedupedMaterialIds);
const needArr = dedupedMaterialIds.map(entry => {
const matchingEntries = arr.filter(arrEntry => entry === arrEntry.Material);
//console.log(matchingEntries);
var summedResult = [];
matchingEntries.reduce(function(res, value) {
if (!res[value.Code]) {
res[value.Code] = {
Quantity: 0,
Code: value.Code
};
summedResult.push(res[value.Code])
}
res[value.Code].Quantity += value.Quantity
return res;
}, {});
//console.log(summedResult);
return {
Material: entry,
CodeQuantity: [...summedResult]
};
});
console.log(needArr);
一种方法应该考虑将 OP 的整个任务分成两个单独的任务。
在中间步骤中,首先将 reduce
material 项的列表转换为(分组的)material 项的映射。
最后一步做中间结果的map
-reduce
on the values
,其中reduce
任务负责总结material的Code
具体Quantity
值 ...
function collectTotalCodeQuantity(index, item) {
const { Code, Quantity } = item;
// access or create the `Code` specific code quantity item.
const codeQuantityItem = (index[Code] ??= { Code, Quantity: 0 });
// sum up a `Code` specific code quantity item's quantity value.
codeQuantityItem.Quantity += Quantity;
return index;
}
function createMaterialGroup(index, item) {
const { Material: materialValue, ...rest } = item;
// create the `CodeQuantity` key in a more generic way from the
// `rest` object which is ... `item` data without `Material` property.
const compoundKey = Object.keys(rest).join('');
// access or create the `Material` specific group.
const group = index[materialValue] ??= { Material: materialValue };
// access or create the `CodeQuantity` specific list.
const list = group[compoundKey] ??= [];
// push the `rest` object into the `CodeQuantity` specific list.
list.push(rest);
return index;
}
const materialDataItemList = [{
"Material": "123",
"Code": "AAA",
"Quantity": 1
}, {
"Material": "123",
"Code": "BBB",
"Quantity": 2
}, {
"Material": "123",
"Code": "BBB",
"Quantity": 2
}, {
"Material": "456",
"Code": "AAA",
"Quantity": 7
}];
const totalCodeQuantityItemList = Object
.values(
materialDataItemList.reduce(createMaterialGroup, {})
)
.map(materialGroup => {
materialGroup.CodeQuantity = Object.values(
materialGroup.CodeQuantity.reduce(collectTotalCodeQuantity, {})
);
return materialGroup;
});
console.log({ totalCodeQuantityItemList });
console.log(
'... intermediate process result ... map of (grouped) material items ...',
materialDataItemList.reduce(createMaterialGroup, {})
);
.as-console-wrapper { min-height: 100%!important; top: 0; }
编辑
Moin! how can I add a new key "CodeQuantityGesamt" where the values of all "Quantity" of a "Material" is summed? example:
{
"Material": "123",
"CodeQuantityGesamt": 5,
"CodeQuantity": [{
"Code": "AAA",
"Quantity": 1
}, {
"Code": "BBB",
"Quantity": 4
}]
}
– InFlames82
这可以通过改变映射任务来实现...
.map(materialGroup => {
materialGroup.CodeQuantity = Object.values(
materialGroup.CodeQuantity.reduce(collectTotalCodeQuantity, {})
);
return materialGroup;
});
...例如...
.map(materialGroup => Object.assign(
materialGroup,
materialGroup.CodeQuantity.reduce(collectCodeQuantityTotals, {})
));
... 调整实现并更改前 collectTotalCodeQuantity
reducer 函数的名称,该函数变为 collectCodeQuantityTotals
.
function collectCodeQuantityTotals(quantities, item, idx, arr) {
const { Code, Quantity } = item;
let {
CodeQuantityTotal = 0,
CodeQuantity = [],
index = {},
} = quantities;
// access ...
let codeQuantityItem = index[Code];
// ... or create the `Code` specific code quantity item.
if (!codeQuantityItem) {
codeQuantityItem = index[Code] = { Code, Quantity: 0 };
// push a newly created item into the CodeQuantity list.
CodeQuantity.push(codeQuantityItem);
}
// sum up a `Code` specific code quantity item's quantity value.
codeQuantityItem.Quantity += Quantity;
// sum up the total (or overall) code quantity value.
CodeQuantityTotal += Quantity;
// return a full collector/accumulator object as long as
// the reduce task takes place because `index` is needed
// as lookup, but return, as the final result, an object
// without the `index` property.
return (idx < arr.length - 1)
&& { CodeQuantityTotal, CodeQuantity, index }
|| { CodeQuantityTotal, CodeQuantity };
}
function createMaterialGroup(index, item) {
const { Material: materialValue, ...rest } = item;
// create the `CodeQuantity` key in a more generic way from the
// `rest` object which is ... `item` data without `Material` property.
const compoundKey = Object.keys(rest).join('');
// access or create the `Material` specific group.
const group = index[materialValue] ??= { Material: materialValue };
// access or create the `CodeQuantity` specific list.
const list = group[compoundKey] ??= [];
// push the `rest` object into the `CodeQuantity` specific list.
list.push(rest);
return index;
}
const materialDataItemList = [{
"Material": "123",
"Code": "AAA",
"Quantity": 1
}, {
"Material": "123",
"Code": "BBB",
"Quantity": 2
}, {
"Material": "123",
"Code": "BBB",
"Quantity": 2
}, {
"Material": "456",
"Code": "AAA",
"Quantity": 7
}];
const totalCodeQuantityItemList = Object
.values(
materialDataItemList.reduce(createMaterialGroup, {})
)
.map(materialGroup => Object.assign(
materialGroup,
materialGroup.CodeQuantity.reduce(collectCodeQuantityTotals, {})
));
console.log({ totalCodeQuantityItemList });
console.log(
'... intermediate process result ... map of (grouped) material items ...',
materialDataItemList.reduce(createMaterialGroup, {})
);
.as-console-wrapper { min-height: 100%!important; top: 0; }
我正在尝试创建一个对象,该对象将填充现有对象的值。在我的例子中,它应该根据“Material”得到一个包含“代码”和“数量”的对象列表。另外,如果“Material”和“Code”相同,则“Quantity”要相加。 我希望你能从我的例子中明白我的意思。谢谢
const arr = [{
"Material": "123",
"Code": "AAA",
"Quantity": 1
}, {
"Material": "123",
"Code": "BBB",
"Quantity": 2
}, {
"Material": "123",
"Code": "BBB",
"Quantity": 2
}, {
"Material": "456",
"Code": "CCC",
"Quantity": 7
}]
var arrResult = [{
"Material": "123",
"CodeQuantity": [{
"Code": "AAA",
"Quantity": 1
}, {
"Code": "BBB",
"Quantity": 4
}]
}, {
"Material": "456",
"CodeQuantity": [{
"Code": "CCC",
"Quantity": 7
}]
}]
console.log(arr)
console.log("Result:", arrResult)
试试这个
const arr = [{
"Material": "123",
"Code": "AAA",
"Quantity": 1
}, {
"Material": "123",
"Code": "BBB",
"Quantity": 2
}, {
"Material": "123",
"Code": "BBB",
"Quantity": 2
}, {
"Material": "456",
"Code": "CCC",
"Quantity": 7
}];
let group = arr.reduce((r, a) => {
r[a.Material] = [...r[a.Material] || [], a];
return r;
}, {});
var newArr = Object.keys(group).map(key => {
var elem = group[key];
var b = elem.map(e => {
return {
Code: e.Code,
Quantity: e.Quantity
}
});
var filteredArr = [];
b.map(i => {
var item = filteredArr.find(n => n.Code == i.Code);
if (item) {
item.Quantity += i.Quantity;
} else {
filteredArr.push(i);
}
})
return {
Material: key,
CodeQuantity: filteredArr
}
});
console.log(newArr);
更新了解决方案以符合您的期望。 这这。希望它能解决您的用例。
const arr = [{
"Material": "123",
"Code": "AAA",
"Quantity": 1
}, {
"Material": "123",
"Code": "BBB",
"Quantity": 2
}, {
"Material": "123",
"Code": "BBB",
"Quantity": 2
}, {
"Material": "456",
"Code": "CCC",
"Quantity": 7
}]
var arrResultExpected = [{
"Material": "123",
"CodeQuantity": [{
"Code": "AAA",
"Quantity": 1
}, {
"Code": "BBB",
"Quantity": 4
}]
}, {
"Material": "456",
"CodeQuantity": [{
"Code": "CCC",
"Quantity": 7
}]
}]
//console.log(arr)
//console.log("ExpecredResult:", arrResultExpected)
const materialIds = arr.map(a => a.Material);
//console.log(materialIds);
const dedupedMaterialIds = [...new Set(materialIds)]
//console.log(dedupedMaterialIds);
const needArr = dedupedMaterialIds.map(entry => {
const matchingEntries = arr.filter(arrEntry => entry === arrEntry.Material);
//console.log(matchingEntries);
var summedResult = [];
matchingEntries.reduce(function(res, value) {
if (!res[value.Code]) {
res[value.Code] = {
Quantity: 0,
Code: value.Code
};
summedResult.push(res[value.Code])
}
res[value.Code].Quantity += value.Quantity
return res;
}, {});
//console.log(summedResult);
return {
Material: entry,
CodeQuantity: [...summedResult]
};
});
console.log(needArr);
一种方法应该考虑将 OP 的整个任务分成两个单独的任务。
在中间步骤中,首先将 reduce
material 项的列表转换为(分组的)material 项的映射。
最后一步做中间结果的map
-reduce
on the values
,其中reduce
任务负责总结material的Code
具体Quantity
值 ...
function collectTotalCodeQuantity(index, item) {
const { Code, Quantity } = item;
// access or create the `Code` specific code quantity item.
const codeQuantityItem = (index[Code] ??= { Code, Quantity: 0 });
// sum up a `Code` specific code quantity item's quantity value.
codeQuantityItem.Quantity += Quantity;
return index;
}
function createMaterialGroup(index, item) {
const { Material: materialValue, ...rest } = item;
// create the `CodeQuantity` key in a more generic way from the
// `rest` object which is ... `item` data without `Material` property.
const compoundKey = Object.keys(rest).join('');
// access or create the `Material` specific group.
const group = index[materialValue] ??= { Material: materialValue };
// access or create the `CodeQuantity` specific list.
const list = group[compoundKey] ??= [];
// push the `rest` object into the `CodeQuantity` specific list.
list.push(rest);
return index;
}
const materialDataItemList = [{
"Material": "123",
"Code": "AAA",
"Quantity": 1
}, {
"Material": "123",
"Code": "BBB",
"Quantity": 2
}, {
"Material": "123",
"Code": "BBB",
"Quantity": 2
}, {
"Material": "456",
"Code": "AAA",
"Quantity": 7
}];
const totalCodeQuantityItemList = Object
.values(
materialDataItemList.reduce(createMaterialGroup, {})
)
.map(materialGroup => {
materialGroup.CodeQuantity = Object.values(
materialGroup.CodeQuantity.reduce(collectTotalCodeQuantity, {})
);
return materialGroup;
});
console.log({ totalCodeQuantityItemList });
console.log(
'... intermediate process result ... map of (grouped) material items ...',
materialDataItemList.reduce(createMaterialGroup, {})
);
.as-console-wrapper { min-height: 100%!important; top: 0; }
编辑
Moin! how can I add a new key "CodeQuantityGesamt" where the values of all "Quantity" of a "Material" is summed? example:
{ "Material": "123", "CodeQuantityGesamt": 5, "CodeQuantity": [{ "Code": "AAA", "Quantity": 1 }, { "Code": "BBB", "Quantity": 4 }] }
– InFlames82
这可以通过改变映射任务来实现...
.map(materialGroup => {
materialGroup.CodeQuantity = Object.values(
materialGroup.CodeQuantity.reduce(collectTotalCodeQuantity, {})
);
return materialGroup;
});
...例如...
.map(materialGroup => Object.assign(
materialGroup,
materialGroup.CodeQuantity.reduce(collectCodeQuantityTotals, {})
));
... 调整实现并更改前 collectTotalCodeQuantity
reducer 函数的名称,该函数变为 collectCodeQuantityTotals
.
function collectCodeQuantityTotals(quantities, item, idx, arr) {
const { Code, Quantity } = item;
let {
CodeQuantityTotal = 0,
CodeQuantity = [],
index = {},
} = quantities;
// access ...
let codeQuantityItem = index[Code];
// ... or create the `Code` specific code quantity item.
if (!codeQuantityItem) {
codeQuantityItem = index[Code] = { Code, Quantity: 0 };
// push a newly created item into the CodeQuantity list.
CodeQuantity.push(codeQuantityItem);
}
// sum up a `Code` specific code quantity item's quantity value.
codeQuantityItem.Quantity += Quantity;
// sum up the total (or overall) code quantity value.
CodeQuantityTotal += Quantity;
// return a full collector/accumulator object as long as
// the reduce task takes place because `index` is needed
// as lookup, but return, as the final result, an object
// without the `index` property.
return (idx < arr.length - 1)
&& { CodeQuantityTotal, CodeQuantity, index }
|| { CodeQuantityTotal, CodeQuantity };
}
function createMaterialGroup(index, item) {
const { Material: materialValue, ...rest } = item;
// create the `CodeQuantity` key in a more generic way from the
// `rest` object which is ... `item` data without `Material` property.
const compoundKey = Object.keys(rest).join('');
// access or create the `Material` specific group.
const group = index[materialValue] ??= { Material: materialValue };
// access or create the `CodeQuantity` specific list.
const list = group[compoundKey] ??= [];
// push the `rest` object into the `CodeQuantity` specific list.
list.push(rest);
return index;
}
const materialDataItemList = [{
"Material": "123",
"Code": "AAA",
"Quantity": 1
}, {
"Material": "123",
"Code": "BBB",
"Quantity": 2
}, {
"Material": "123",
"Code": "BBB",
"Quantity": 2
}, {
"Material": "456",
"Code": "AAA",
"Quantity": 7
}];
const totalCodeQuantityItemList = Object
.values(
materialDataItemList.reduce(createMaterialGroup, {})
)
.map(materialGroup => Object.assign(
materialGroup,
materialGroup.CodeQuantity.reduce(collectCodeQuantityTotals, {})
));
console.log({ totalCodeQuantityItemList });
console.log(
'... intermediate process result ... map of (grouped) material items ...',
materialDataItemList.reduce(createMaterialGroup, {})
);
.as-console-wrapper { min-height: 100%!important; top: 0; }