Angular *ngFor:仅显示唯一的 属性 "category" 值和每个 "category" 中的最低价格

Angular *ngFor: Display only unique property "category" value and lowest price in each "category"

我有一个数组,其中包含具有“类别”和“价格”属性的对象,在 Angular 应用程序中,我只需要显示“类别”的唯一值 属性(示例:经济舱、高级舱和豪华舱)以及该类别中的最低价格。我尝试过滤它但无法实现。那么,您能否帮助如何在 Angular 中实现这一点?谢谢。

在这个例子中,我需要显示:

Economy - Starts from 250USD

Premium - Starts from 400USD

Deluxe - Starts from 600USD

"hotelRooms": [
{
    "price": {
        "total": 250,
        "currency": "USD"
    },
    "category": "Economy",
    "subcategory": "single",
},
{
    "price": {
        "total": 350,
        "currency": "USD"
    },
    "category": "Economy",
    "subcategory": "double",
},
{
    "price": {
        "total": 450,
        "currency": "USD"
    },
    "category": "Economy",
    "subcategory": "family",
},
{
    "price": {
        "total": 400,
        "currency": "USD"
    },
    "category": "Premium",
    "subcategory": "single",
},
{
    "price": {
        "total": 500,
        "currency": "USD"
    },
    "category": "Premium",
    "subcategory": "double",
},
{
    "price": {
        "total": 600,
        "currency": "USD"
    },
    "category": "Deluxe",
    "subcategory": "single",
},
{
    "price": {
       "total": 700,
       "currency": "USD"
    },
    "category": "Deluxe",
    "subcategory": "double",
}
]

在Angular中:

<div *ngFor="let room of hotelRooms">
    <span class="bold">{{ room.category }}</span> - Starts from {{ room.price.total}}{{ room.price.currency}}
</div>

根据我对这个问题的理解,您需要按 category 分组,然后为每个类别获取最低的 price.amount

概念 (TL;DR)

  1. 按类别分组

    1.1 如果类别数组不存在,则为每个类别创建一个数组。否则重新使用创建的类别数组。

    1.2 从每个类别数组中,根据price.amount找到最低的记录。

    1.3 如果结果(from 1.2) return没有值(undefined),首先将类别数组重置为空数组 并将 current 记录添加到类别数组。 这样可以确保每个类别只有 1 条价格最低的记录。否则忽略它。

  2. 数据转换

    2.1 通过键迭代从每个类别中获取项目。它将 return 个数组。

    2.2 将多个数组(从 2.1)连接到一个数组中。

let groupByCategories = [];

groupByCategories = this.hotelRooms.reduce(function (previous, current) {
  previous[current.category] = previous[current.category] || [];

  let lowest = previous[current.category].find(
    (x) =>
      x.price.total < current.price.total
  );

  if (!lowest) {
    previous[current.category] = [];
    previous[current.category].push(current);
  }

  return previous;
}, Object.create(null));

this.hotelRooms = [].concat(
  ...Object.keys(groupByCategories).map((key) => {
    return groupByCategories[key];
  })
);

Sample Demo on StackBlitz