从对象数组中计算属性的滚动增量

问题描述 投票:0回答:1

我有一个这种结构的对象数组

- 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]
    },
    ...
]
javascript arrays data-structures lodash
1个回答
0
投票

使用

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>

© www.soinside.com 2019 - 2024. All rights reserved.