javascript - 如何在没有突变的情况下按功能创建有效的组?

标签 javascript reason rescript

有没有一种方法可以有效地实现按功能分组而不发生突变?
天真的实现:

  • ReScript playground
  • JavaScript(见下文)

  • var messages = [
      {insertedAt: "2021-01-10"},
      {insertedAt: "2021-01-12"},
      {insertedAt: "2021-01-13"},
      {insertedAt: "2021-01-13"},
      {insertedAt: "2021-01-13"},
      {insertedAt: "2021-01-14"},
      {insertedAt: "2021-01-15"},
      {insertedAt: "2021-01-15"},
      {insertedAt: "2021-01-16"},
      {insertedAt: "2021-01-17"},
      {insertedAt: "2021-01-17"},
      {insertedAt: "2021-01-17"},
      {insertedAt: "2021-01-18"},
      {insertedAt: "2021-01-18"},
    ]
    
    var messagesGroupedByDate = messages.reduce(function (data, message) {
      if (
        data.some(function (point) {
          return point.date === message.insertedAt;
        })
      ) {
        return data.map(function (point) {
          if (point.date === message.insertedAt) {
            return {
              date: point.date,
              count: (point.count + 1) | 0,
            };
          } else {
            return point;
          }
        });
      } else {
        return data.concat([
          {
            date: message.insertedAt,
            count: 1,
          },
        ]);
      }
    }, []);
    
    
    console.log(messagesGroupedByDate);

    为了争论,没有必要使它更通用。我面临的问题是我循环了三次:
  • 一次与 Array.prototype.reduce这是循环 messages 所必需的
  • 一次与 Array.prototype.some查看结果数组中是否已存在日期键
  • 在日期键已经存在的情况下,我们再次循环 Array.prototype.map更新数组的特定元素
  • 否则,返回一个包含新元素
  • 的新数组。

    如果在 ReScript 中没有真正提高效率的好方法,那么我总是可以为这个函数使用原始 JavaScript,但我很好奇是否有可能在没有突变的情况下有效地做到这一点。

    最佳答案

    只需将数据添加到 Map()然后转换为数组,然后转换为对象。它不会根据您的要求改变任何内容。
    我们可以进一步简化这一点,但现在是凌晨 5:00,我的大脑现在睡着了。

    var messages = [
      {insertedAt: "2021-01-10"},
      {insertedAt: "2021-01-12"},
      {insertedAt: "2021-01-13"},
      {insertedAt: "2021-01-13"},
      {insertedAt: "2021-01-13"},
      {insertedAt: "2021-01-14"},
      {insertedAt: "2021-01-15"},
      {insertedAt: "2021-01-15"},
      {insertedAt: "2021-01-16"},
      {insertedAt: "2021-01-17"},
      {insertedAt: "2021-01-17"},
      {insertedAt: "2021-01-17"},
      {insertedAt: "2021-01-18"},
      {insertedAt: "2021-01-18"},
    ];
    
    const mapped = new Map();
    
    messages.forEach(message => {
        // if date already seen before, increment the count
        if (mapped.has(message.insertedAt)) {
            const count = mapped.get(message.insertedAt);
            mapped.set(message.insertedAt, count+1);
        } else {
            // date never seen before, add to map with initial count
            mapped.set(message.insertedAt, 1);
        }
    });
    
    const msgArr = Array.from(mapped);
    
    const final = msgArr.map(([date, count])=> ({date, count}));
    
    console.log(final);

    关于javascript - 如何在没有突变的情况下按功能创建有效的组?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65783074/

    相关文章:

    javascript - jQuery datepicker 开始日期间隔不显示

    javascript - 单例模块和导入全局 jQuery 对象

    object - 在可扩展对象类型的情况下,我应该如何指向记录字段?

    ocaml - 是否可以使用模块动态创建多态变体类型?

    f# - Ocaml 中是否有单个案例变体的用例?

    javascript - 如何在谷歌地图中添加多个标记

    javascript - 是否可以仅通过属性值选择元素?

    ocaml - 未绑定(bind)记录字段 id 错误

    rescript - 如何在Rescript中强制函数返回 'unit'?

    ocaml - ReScript 中的无限列表/流