我有一个这种结构的对象数组
- day
- dimension
- sub-dimension
...
- sub-sub-dimension
- measure1, measure2,...
并且想要转换成这种结构以输入仪表板模板,其中“diff”是 DoD 差异。
- day
- dimension
- sub-dimension
...
- sub-sub-dimension
- measure1: [value,#diff,%diff]
- measure2: [value,#diff,%diff]
...
到目前为止我最好的逻辑是
dimensionList
的每个值组合进行分组。measureList
中的每个度量组合填充所有日期的值数组。我的最佳尝试在为每个组合生成数组的第一步失败了,而且我的逻辑也不整洁。希望有人可以帮忙,使用包就可以了。
const dimensionList = ["city","category"];
const measureList = ["order","buyer","gmv"];
const newData = [];
measureList.forEach(measure => {
newData.push(
{
measure: measure,
values: _.chain(data)
.groupBy(data,item => dimensionList.map(dim => item[dim]).join('-'))
.mapValues(group => _.map(group, measure))
.value()
}
)
});
示例数据和预期结果
[
{
"day": "2024-01-01",
"city": "A",
"category": "X",
"order": 100,
"buyer": 50,
"gmv": 1000
},
{
"day": "2024-01-01",
"city": "A",
"category": "Y",
"order": 110,
"buyer": 160,
"gmv": 1200
},
{
"day": "2024-01-02",
"city": "A",
"category": "X",
"order": 125,
"buyer": 60,
"gmv": 1400
},
...
]
[
{
"day": "2024-01-01",
"city": "A",
"category": "X",
"order": [100,null,null]
"buyer": [50,null,null]
"gmv": [1000,null,null]
},
{
"day": "2024-01-01",
"city": "A",
"category": "Y",
"order": [110,null,null]
"buyer": [160,null,null]
"gmv": [1200,null,null]
},
{
"day": "2024-01-02",
"city": "A",
"category": "X",
"order": [125,25,0.25]
"buyer": [60,10,0.2]
"gmv": [1400,400,0.4]
},
...
]
使用
Array.map()
迭代数组,并使用 Map
保存具有相同维度的前一项。在每个项目上,从 Map
(或默认 null
)中获取上一个项目,并将其替换为当前项目。计算差异后返回新对象。
const { mapValues, pick } = _;
const dimensionList = ["city","category"];
const measureList = ["order","buyer","gmv"];
const getDimensions = item => dimensionList.map(dim => item[dim]).join('-');
const getMeasures = (curr, prev) => prev === null
? [curr, null, null]
: [curr, curr - prev, (curr - prev) / prev];
const updateItem = (curr, prev) => ({
...curr,
...mapValues(pick(curr, measureList), (v, k) =>
getMeasures(v, prev?.[k] ?? null)
)
});
const mapDiffs = arr => {
const dimMap = new Map();
return arr.map(item => {
const dimensions = getDimensions(item);
const prev = dimMap.get(dimensions) ?? null;
dimMap.set(dimensions, item);
return updateItem(item, prev);
});
};
const arr = [{"day":"2024-01-01","city":"A","category":"X","order":100,"buyer":50,"gmv":1000},{"day":"2024-01-01","city":"A","category":"Y","order":110,"buyer":160,"gmv":1200},{"day":"2024-01-02","city":"A","category":"X","order":125,"buyer":60,"gmv":1400}];
const result = mapDiffs(arr);
console.log(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.21/lodash.min.js" integrity="sha512-WFN04846sdKMIP5LKNphMaWzU7YpMyCU245etK3g/2ARYbPK9Ub18eG+ljU96qKRCWh+quCY7yefSmlkQw1ANQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>