使用groupBy和map使用LoDash和Moment

时间:2016-09-21 21:11:19

标签: javascript lodash

我对lodash缺乏经验,但我相信它可以帮助我将数据转换为所需的格式。我已经尝试过文档中描述的不同级别的方法,但我无法绕过一切。我在这里看过SO,一些博客和文档。我尝试过将groupby和map结合起来,但我无法解决问题。我也不确定如何记录这些步骤。

这是我想要做的,我想采取以下数组并将其转换为数组。有人能指出我正确的方向吗?

原始数据

var mockData = [
      {
        "notice_title": "Bad news",
        "notice_text": "Server is down!",
        "start_date": "2016-09-18T04:00:00Z"
      },
      {
        "notice_title": "Weekly Reminder",
        "notice_text": "Please read the assignment!",
        "start_date": "2016-09-18T04:00:00Z"
      },
      {
        "notice_title": "Sweet",
        "notice_text": "This morning, the new edition of our blog hit stands!",
        "start_date": "2016-09-19T04:00:00Z"
      },
      {
        "notice_title": "Yeah",
        "notice_text": "This is pretty cool",
        "start_date": "2016-09-19T04:00:00Z"
      }

所需数据

var newMockData = [
    { 
        "date": "JAN 18 2016", 
        "messages": [{
            "notice_title": "Bad news",
            "notice_text": "Server is down!",
            "start_date": "2016-09-18T04:00:00Z"
          },
          {
            "notice_title": "Weekly Reminder",
            "notice_text": "Please read the assignment!",
            "start_date": "2016-09-18T04:00:00Z"
          }],
        "date": "JAN 19 2016", 
        "messages": [{
            "notice_title": "Sweet",
            "notice_text": "This morning, the new edition of our blog hit stands!",
            "start_date": "2016-09-19T04:00:00Z"
          },
          {
            "notice_title": "Yeah",
            "notice_text": "This is pretty cool",
            "start_date": "2016-09-19T04:00:00Z"
          }]

}]

更新了lodash

var result = _.chain(mockData)
      .groupBy(function(item) {
        return moment(item.start_date.substring(0,10)).format("MMM-DD-YYYY"); 
      })
      .map((value, key) => {
        return {
          date: key, 
          param: value
        }
      })
      .value();

1 个答案:

答案 0 :(得分:7)

昨天我确实回答了generalhenry,但是,我仍会通过修改前一个来提供答案

var mockData = [
      {
        "notice_title": "Bad news",
        "notice_text": "Server is down!",
        "start_date": "2016-09-18T04:00:00Z"
      },
      {
        "notice_title": "Weekly Reminder",
        "notice_text": "Please read the assignment!",
        "start_date": "2016-09-18T04:00:00Z"
      },
      {
        "notice_title": "Sweet",
        "notice_text": "This morning, the new edition of our blog hit stands!",
        "start_date": "2016-08-19T04:00:00Z"
      },
      {
        "notice_title": "Yeah",
        "notice_text": "This is pretty cool",
        "start_date": "2016-09-19T04:00:00Z"
      }
]

var result = _.chain(mockData)
  .groupBy(datum => moment(datum.start_date).format("MMM DD YYYY").toLocaleUpperCase() )
  .map((messages, date) => ({ date, messages })) //using ES6 shorthand to generate the objects
  .value();

console.log(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.15.1/moment.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.16.1/lodash.min.js"></script>

这里的关键是,当使用_.groupBy时,您可以提供一个定义如何一起收集对象的函数。在这种情况下,这是使用Moment.js将消息的start_date格式化为月 - 日 - 年格式:

moment(datum.start_date).format("MMM DD YYYY")` 

这将解析消息的日期并以<Short month> <day> <year>格式输出。详细了解格式very similar question。然后将该值转换为大写以将“Sep”变换为“SEP”

第二件事是在.map内生成新结构。由于所需的所有信息都已经格式化,所以

{
    "Sep 18 2016": [{
        "notice_title": "Bad news",
        "notice_text": "Server is down!",
        "start_date": "2016-09-18T04:00:00Z"
    }, {
        "notice_title": "Weekly Reminder",
        "notice_text": "Please read the assignment!",
        "start_date": "2016-09-18T04:00:00Z"
    }],
    "Aug 19 2016": [{
        "notice_title": "Sweet",
        "notice_text": "This morning, the new edition of our blog hit stands!",
        "start_date": "2016-08-19T04:00:00Z"
    }],
    "Sep 19 2016": [{
        "notice_title": "Yeah",
        "notice_text": "This is pretty cool",
        "start_date": "2016-09-19T04:00:00Z"
    }]
}

获取密钥并将其转换为属性和值并作为另一个属性添加是一件简单的事情。