使用Lodash和Moment从单个日期开始的天/小时分组数组

时间:2019-04-17 10:10:46

标签: javascript node.js momentjs lodash

我正在尝试转换数组,以使其在呈现视图时易于使用

我现在有此示例代码

let arr = [
    {
        date: d.setDate(d.getDate() - 1),
        name: "john",
        country: "AU",
        text: "Hey"
    },
    {
        date: d.setDate(d.getDate() - 1),
        name: "jake",
        country: "US",
        text: "Hey"
    },
    {
        date:d.setDate(d.getDate() - 3),
        name: "jeff",
        country: "US",
        text: "Hey"
    },
    {
        date:d.setDate(d.getDate() - 5),
        name: "jared",
        country: "US",
        text: "Hey"
    },
    {
        date:d.setDate(d.getDate() - 2),
        name: "jane",
        country: "UK",
        text: "Hey"
    }
]

let hours = _.groupBy(arr, (result) => moment(result['date']).startOf('hour').format("LT"));
let day = _.groupBy(arr, (result) => moment(result['date']).startOf('day').format("MMM Do YY"));


console.log(day)

我想要的是按小时将数据分组,而按小时将数据从单个“日期”字符串按天分组(我可以通过_.groupby函数单独执行此操作,但是我希望它输出一个组合数组。

所需的输出应该是这样的:

{
    'Apr 15th 19': [
        {'4 pm':[
            {
                date: 1555318593445,
                name: 'ahmed',
                country: 'AU',
                text: 'Hey'
            }
        ]
    ]
}....

1 个答案:

答案 0 :(得分:1)

使用_.flow()创建一个按天分组的函数,然后映射每天的值并按小时分组:

const { flow, groupBy, mapValues } = _

const fn = flow(
  arr => groupBy(arr, v => moment(v.date).startOf('day').format("MMM Do YY")),
  groups => mapValues(groups, g => _.groupBy(g, v =>
    moment(v.date).startOf('hour').format("LT")
  ))
)

const arr = [{"date":1555318593445,"name":"john","country":"AU","text":"Hey"},{"date":155531859300,"name":"jake","country":"US","text":"Hey"},{"date":1555316593445,"name":"jeff","country":"US","text":"Hey"},{"date":1555316593345,"name":"jared","country":"US","text":"Hey"},{"date":155531659400,"name":"jane","country":"UK","text":"Hey"}]

const result = fn(arr)

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

以及terser lodash / fp版本:

const { flow, groupBy, mapValues } = _

const fn = flow(
  groupBy(v => moment(v.date).startOf('day').format("MMM Do YY")),
  mapValues(_.groupBy(v => moment(v.date).startOf('hour').format("LT")))
)

const arr = [{"date":1555318593445,"name":"john","country":"AU","text":"Hey"},{"date":155531859300,"name":"jake","country":"US","text":"Hey"},{"date":1555316593445,"name":"jeff","country":"US","text":"Hey"},{"date":1555316593345,"name":"jared","country":"US","text":"Hey"},{"date":155531659400,"name":"jane","country":"UK","text":"Hey"}]

const result = fn(arr)

console.log(result)
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.24.0/moment.min.js"></script>
<script src='https://cdn.jsdelivr.net/g/lodash@4(lodash.min.js+lodash.fp.min.js)'></script>

评论问答:

流量与连锁有何不同?

Flow生成一个函数,该函数按顺序运行代码,并将一个函数调用的结果传递给下一个函数。 lodash链运行代码,但尝试进行惰性求值,并将多个调用组合到一个调用中,这意味着.map.filter链仅将数组迭代一次。

但是,懒惰是有代价的,您需要导入整个lodash模块才能正常工作。在使用流程时,您可以仅导入所需的功能。

为什么mapvalues是第二步?

第1组的结果是一个对象{date:{},date:{}),您需要将每个对象值单独分组。为此,您需要映射每个日期的值,并按小时将其分组。