【问题标题】:Javascript JSON transform using Map, Reduce, Aggregate使用 Map、Reduce、Aggregate 的 Javascript JSON 转换
【发布时间】:2022-02-14 05:10:13
【问题描述】:

我正在拼命想弄清楚这种转变。

这是 JSON 的格式

我有:

{
    "itineraryId": "063fc878-b118-49fc-9106-39d51f647c9e",
    "reservations": [
        {
            "confirmNumber": "54047SC008976",
            "startDate": "2021-11-20T00:00:00.000Z"
        },
        {
            "confirmNumber": "54047SC008975",
            "startDate": "2021-11-13T00:00:00.000Z"
        },
        {
            "confirmNumber": "54058SC007379",
            "startDate": "2021-08-13T00:00:00.000Z"
        }
    ]
}

我需要:

[{
    "itineraryId": "063fc878-b118-49fc-9106-39d51f647c9e",
    "month": "November 2021",
    "reservations": [{
            "confirmNumber": "54047SC008976",
            "startDate": "2021-11-20T00:00:00.000Z"
        },
        {
            "confirmNumber": "54047SC008975",
            "startDate": "2021-11-13T00:00:00.000Z"
        }
    ]
}, {
    "itineraryId": "063fc878-b118-49fc-9106-39d51f647c9e",
    "month": "August 2021",
    "reservations": [{
        "confirmNumber": "54058SC007379",
        "startDate": "2021-08-13T00:00:00.000Z"
    }]
}]

我需要这样才能在我的react native app 中构建一个SectionList。我尝试了很多不同的选项(聚合+映射+减少),但我无法将其转换为这种格式。有什么指南可以帮助我吗?


这个问题要复杂得多,但我通过删除所有不需要的数据属性来简化它。通过查看 SectionList 页面中的示例并找出

的结构,我能够找出我需要的结构

编辑:粘贴当我遵循其中一种解决方案时的样子的图片。 2022 年 11 月出现在 2021 年 11 月之前

【问题讨论】:

  • @serlite 嘿,我已经用它的截图更新了这个问题

标签: javascript node.js reactjs json react-native


【解决方案1】:

我经常希望在 JavaScript 中提供某种简单的“分组依据”功能,但您可以使用 reduce() 实现相同的效果。本质上,您可以通过创建或更新组来构建一组分组结果,具体取决于在每次调用 reducer 函数期间它是否已经存在:

const monthNames = ["January", "February", "March", "April", "May", "June",
  "July", "August", "September", "October", "November", "December"
];

const initial = {
  "itineraryId": "063fc878-b118-49fc-9106-39d51f647c9e",
  "reservations": [{
      "confirmNumber": "54047SC008976",
      "startDate": "2021-11-20T00:00:00.000Z"
    },
    {
      "confirmNumber": "54047SC008975",
      "startDate": "2021-11-13T00:00:00.000Z"
    },
    {
      "confirmNumber": "54058SC007379",
      "startDate": "2021-08-13T00:00:00.000Z"
    },
    {
      "confirmNumber": "54047SC008971",
      "startDate": "2020-11-13T00:00:00.000Z"
    },
    {
      "confirmNumber": "54047SC008973",
      "startDate": "2022-11-13T00:00:00.000Z"
    }
  ]
};

const groupedReservations = initial.reservations
  .sort((reservationA, reservationB) => {
    // Sort descending according to startDate
    return new Date(reservationB.startDate) - new Date(reservationA.startDate);
  })
  .reduce((reservationGroups, reservation) =>
  {
    // Calculate the key that uniquely identifies the group, then look it up
    const date = new Date(reservation.startDate);
    const reservationMonth = monthNames[date.getMonth()] + " " + date.getFullYear();
    const existingGroup = reservationGroups.find(group => group.month === reservationMonth);

    // If the group doesn't exist, create it - otherwise, add the reservation to it
    if (!existingGroup) {
      reservationGroups.push({
        itineraryId: initial.itineraryId,
        month: reservationMonth,
        reservations: [reservation]
      });
    } else {
      existingGroup.reservations.push(reservation);
    }

    return reservationGroups;
  }, []);

console.log(groupedReservations);

请注意,我在这里基本上将itineraryId 视为事后的想法,因为非规范化数据似乎不是一个重要的步骤。如果您的代码上下文需要不同的内容,请告诉我。

【讨论】:

  • 当我在 2022 年 11 月添加另一个有预订的商品时,“2022 年 11 月”商品显示在“2021 年 11 月”下方。知道我可以做些什么来解决年份问题吗?
  • 嗯,不能确定 - 更新后的数据是什么样的?这很奇怪,因为字符串比较非常明确。
  • @Saamer 你在November 2022 benchmark 上测试过下面的解决方案吗?
  • @Saamer 我已经编辑了我的代码 sn-p 以保留 2022 年 11 月的预订,这似乎已正确分组到其自己的 2022 年 11 月项目中。这也是你们引入新数据的方式吗?
  • @Saamer 根据您在上次编辑中说明的问题,我明白您的意思。我在处理过程中添加了一个基本排序(基于 startDate),因此预订(及其组)将以逻辑顺序出现。如果您还有其他问题,请告诉我!
【解决方案2】:

这里是缩小的实现



// Convert ISO date to human readable date : August 2021

const formatYearMonth = (dateISO) => {
 
const formatYearMonth = (dateISO) => {

  const monthNames = ["January", "February", "March", "April", "May", "June",
  "July", "August", "September", "October", "November", "December"
];
  const parsedDate =  new Date(dateISO)

  const year = parsedDate.getFullYear()
  const month = monthNames[parsedDate.getMonth()]

  return `${month} ${year}`;
};

  return `${month} ${year}`;
};

const getItineraryMonths = (reservations) => {
  let months = {};

  reservations.forEach((reservation) => {
    const formattedMonth = formatYearMonth(reservation.startDate);

    months[formattedMonth] = formattedMonth;
  });

  return Object.keys(months);
};

// Get reservation in specified month for specific itinerary

const getReservationsInMonth = (reservations, formatedMonthIn) => {
  return reservations.filter((reservation) => {
    const formattedMonth = formatYearMonth(reservation.startDate);

    return formattedMonth === formatedMonthIn;
  });
};

// Reformat JSON response

const formatJsonResponse = (response) => {
  const itineraryMonths = getItineraryMonths(response.reservations);

  const formattedResult = itineraryMonths.map((month) => {
    return {
      itineraryId: response.itineraryId,
      month,
      reservations: getReservationsInMonth(response.reservations, month),
    };
  });

  return formattedResult;
};

console.log(formatJsonResponse(input));


测试解决方案-https://replit.com/@EmmanuelBYIRING/json-sanitise#index.js

【讨论】:

  • Byiringiro 我还没有尝试过,因为它需要添加另一个库,我非常接近让它与其他解决方案一起使用。但我可以试试这个
  • 我删除了日期依赖库,检查更新解决方案
猜你喜欢
  • 1970-01-01
  • 2021-07-08
  • 1970-01-01
  • 1970-01-01
  • 2016-02-27
  • 2020-03-21
  • 1970-01-01
  • 2023-02-05
  • 2018-08-17
相关资源
最近更新 更多