我有一个与此类似的对象:
[
{
origin: "XX",
destination: "YY",
volume: 500
},
{
origin: "ZZ",
destination: "YY",
volume: 500
}
]
我想制作地图并减少这些对象以获取某个属性的卷总和,在我的情况下为目的地。
所以我希望得到类似的东西:
[
{
destination: "YY",
volume: 1000
}
]
谢谢。
答案 0 :(得分:0)
试试这个;
var array = [{
origin: "XX",
destination: "YY",
volume: 500
},
{
origin: "ZZ",
destination: "YY",
volume: 500
}
];
function sumFn(a, propType, propVal) {
var i = 0;
array.forEach(function(a) {
if (a[propType] && a[propType] === propVal) {
i += a.volume;
}
});
console.log({
[propType]: propVal,
volume: i
});
}
sumFn(array, "destination", "YY");
答案 1 :(得分:0)
您尝试按destination
属性对数组进行分组。这里是TypeScript中的一般groupBy
函数,它创建Map
(ES2015或更高版本,如果需要,可以使用polyfill,如果您知道值将始终是字符串属性,则替换为普通对象)从destination
值到具有destination
的值的对象数组:
function groupBy<T, K extends keyof T>(key: K, arr: T[]): Map<T[K], T[]> {
const map = new Map<T[K], T[]>();
arr.forEach(t => {
if (!map.has(t[key])) {
map.set(t[key], []);
}
map.get(t[key])!.push(t);
})
return map;
}
然后,根据您的意见,
const input = [
{
origin: "XX",
destination: "YY",
volume: 500
},
{
origin: "ZZ",
destination: "YY",
volume: 500
}
]
您可以将分组Map
的条目数组映射到包含组destination
的对象数组和每个组的volume
之和:
const output = Array.from(groupBy("destination", input).entries())
.map(([dest, objs]) => ({
destination: dest,
volume: objs.reduce((acc, cur) => acc + cur.volume, 0)
}))
console.log(JSON.stringify(output)); // produces the desired output
希望有所帮助;祝你好运!
它适用于我今天使用v2.5.1的in the TypeScript Playground。
答案 2 :(得分:0)
如果使用Array.reduce
的强大功能,则甚至可以提供与任何数据结构无关的通用基本收集器方法,但使用它的第一个collector
或accumulator
参数来承载数据oder中特定于结构的getter / setter功能,用于操作此特定数据。
正确操作OP给定示例代码的实现可能看起来类似于以下代码......
var dataList = [{
origin: "XX",
destination: "YY",
volume: 500
}, {
origin: "ZZ",
destination: "YY",
volume: 500
}, {
origin: "XX",
destination: "AA",
volume: 200
}, {
origin: "ZZ",
destination: "AA",
volume: 100
}];
function collectSourceValueConnectedTargetSummaries(collector, dataItem) { // a generic data structure agnostic summary approach ...
var registry = collector.registry;
var sourceValue = collector.getSourceValue(dataItem);
var summaryItem = registry[sourceValue];
if (!summaryItem) {
summaryItem = registry[sourceValue] = Object.assign({}, collector.summaryItem);
collector.putSummarySource(summaryItem, sourceValue);
collector.summaryList.push(summaryItem);
}
collector.summarizeTarget(summaryItem, collector.getTargetValue(dataItem));
return collector;
}
var result = dataList.reduce(collectSourceValueConnectedTargetSummaries, { // ... that makes use of data structure specific methods.
registry: {},
// this two methods just read data and their's implementation reflects the data structure that gets operated.
getSourceValue: function (dataItem) { return dataItem.destination },
getTargetValue: function (dataItem) { return dataItem.volume },
// the next two methods do control the mapping process (the output) of all summary data.
putSummarySource: function (summaryItem, value) { summaryItem.destination = value; },
summarizeTarget: function (summaryItem, value) { summaryItem.volume = (summaryItem.volume + value); },
summaryItem: { /*destination: '', */volume: 0 },
summaryList: []
}).summaryList;
console.log('dataList : ', dataList);
console.log('reduced dataList / result : ', result);
.as-console-wrapper { max-height: 100%!important; top: 0; }