【问题标题】:Iterate over grouped object in Typescript迭代打字稿中的分组对象
【发布时间】:2020-09-14 15:32:31
【问题描述】:

我有一个通过 lodash groupBy 函数映射分组数据的对象, 迭代集合并检索以下信息的最佳方法是什么:

  • totalProductNumber,
  • totalProductSum = Sum(productsNumberInGroup * 价格)
  • productsNumberPerGroup

所以输出可能是

let result = {
totalProductNumber: 8,
totalProductSum: 17,
productsNumberPerGroup: [{1:2}, {2:3}, {3:3}] // or sth. like this
}
interface IProduct {
  name: string;
  color: string;
  price: string;
 id: number
 }

    const products = {
  "1": [{
      "name": "Jim",
      "color": "blue",
      "price": 1,
      "id": 1
    },
    {
      "name": "Jim",
      "color": "blue",
      "price": 1,
      "id": 1
    }
  ],
  "2": [{
      "name": "Eddie",
      "color": "green",
      "price": 2,
      "id": 2
    },
    {
      "name": "Eddie",
      "color": "green",
      "price": 2,
      "id": 2
    },
    {
      "name": "Eddie",
      "color": "green",
      "price": 2,
      "id": 2
    }
  ],
  "3": [{
      "name": "Ela",
      "color": "pink",
      "price": 3,
      "id": 3
    },
    {
      "name": "Ela",
      "color": "pink",
      "price": 3,
      "id": 3
    },
    {
      "name": "Ela",
      "color": "pink",
      "price": 3,
      "id": 3
    }
  ]
}

我的假设是使用 Object.entries 或 Object.values

  let totalSum: number;
  let totalPrices: number[];
Object.values(products)
      .map((prod) => {
        (prod as IProduct[]).map((p) => {
            this.totalPrices.push(Number(p.price)); // here getting Cannot read property 'push' of undefined
        });
      });

【问题讨论】:

  • 你只声明了totalPrices,你没有给它赋值。尝试为其分配一个空数组。

标签: javascript typescript ecmascript-6 lodash


【解决方案1】:

样式可变

interface IProduct {
  name: string
  color: string
  price: number
  id: number
}

type Products = Record<string, IProduct[]>

const products: Products = { ... }

let totalProductNumber = 0
let totalProductSum = 0
let productsNumberPerGroup: [string, number][] = []

Object.entries(products).map(([grpId, grpProducts]) => {
  totalProductNumber = totalProductNumber + grpProducts.length
  totalProductSum = totalProductSum + grpProducts.reduce((acc, curr) => acc + curr.price, 0)
  productsNumberPerGroup = [...productsNumberPerGroup, [grpId, grpProducts.length]]
})

console.log(totalProductNumber) // 8
console.log(totalProductSum) // 17
console.log(productsNumberPerGroup) //[ [ '1', 2 ], [ '2', 3 ], [ '3', 3 ] ]

具有不可变样式


type Result = [
  totalProductNumber: number,
  totalProductSum: number,
  productsNumberPerGroup: [string, number][]
]
const initial: Result = [0, 0, []]

const [totalNum, totalSum, prdPerGrp] = Object.entries(products).reduce<Result>(
  ([num, sum, perGrp], [grpId, grpProducts]) => {
    return [
      num + grpProducts.length,
      sum + grpProducts.reduce((acc, curr) => acc + curr.price, 0),
      [...perGrp, [grpId, grpProducts.length]]
    ]
  },
  initial
)

console.log(totalNum) // 8
console.log(totalSum) // 17
console.log(prdPerGrp) // [ [ '1', 2 ], [ '2', 3 ], [ '3', 3 ] ]

【讨论】:

    【解决方案2】:

    你应该做两个改变

    let totalPrices: number[];
    

    let totalPrices: number[] = [];
    

    界面的更多变化

    interface IProduct {
      name: string;
      color: string;
      price: string;
      id: number
    }
    

    改变

    price: string;
    

    price: number;
    

    【讨论】:

      猜你喜欢
      • 2020-06-22
      • 1970-01-01
      • 2016-11-25
      • 2022-12-05
      • 2020-03-04
      • 2022-12-14
      • 1970-01-01
      • 2020-07-26
      • 2017-05-12
      相关资源
      最近更新 更多