【问题标题】:Optimising sorting time in half an hour interval arrays优化半小时间隔数组中的排序时间
【发布时间】:2017-11-20 22:06:13
【问题描述】:

我开发了一个小函数,可以对具有 lastAccessedTime 将日期时间信息放入 sortedData 数组中,该数组包含相同的信息,但以半小时为间隔(preparedData 是一个仅包含开始和结束时间间隔信息的数组)。

我的问题是:这是实现预期结果的最佳方式吗?随着数据数组变大,prepareData() 变慢,所以我需要尽量减少准备时间。 为结帐逻辑创建了一个小小提琴https://jsfiddle.net/mtcljiljana/nvfq6h9h/

const data = [{"lastAccessedTime":"2017-11-16T07:15:41Z","path":"/login.htm"},{"lastAccessedTime":"2017-11-16T07:32:42Z","path":"/login.htm"},{"lastAccessedTime":"2017-11-16T07:32:47Z","path":"/concurrent_users.htm"},{"lastAccessedTime":"2017-11-16T07:36:02Z","path":"/concurrent_users.htm"},{"lastAccessedTime":"2017-11-16T07:36:55Z","path":"/concurrent_users.htm"},{"lastAccessedTime":"2017-11-16T07:37:28Z","path":"/concurrent_users.htm"},{"lastAccessedTime":"2017-11-16T07:39:48Z","path":"/concurrent_users.htm"},{"lastAccessedTime":"2017-11-16T07:40:47Z","path":"/concurrent_users.htm"},{"lastAccessedTime":"2017-11-16T07:42:31Z","path":"/concurrent_users.htm"},{"lastAccessedTime":"2017-11-16T07:44:06Z","path":"/concurrent_users.htm"},{"lastAccessedTime":"2017-11-16T07:46:04Z","path":"/concurrent_users.htm"},{"lastAccessedTime":"2017-11-16T07:46:43Z","path":"/concurrent_users.htm"},{"lastAccessedTime":"2017-11-16T07:50:31Z","path":"/concurrent_users.htm"},{"lastAccessedTime":"2017-11-16T07:52:54Z","path":"/concurrent_users.htm"},{"lastAccessedTime":"2017-11-16T07:53:53Z","path":"/concurrent_users.htm"},{"lastAccessedTime":"2017-11-16T08:14:00Z","path":"/concurrent_users.htm"},{"lastAccessedTime":"2017-11-16T08:14:44Z","path":"/concurrent_users.htm"},{"lastAccessedTime":"2017-11-16T08:16:20Z","path":"/concurrent_users.htm"},{"lastAccessedTime":"2017-11-16T08:17:32Z","path":"/concurrent_users.htm"},{"lastAccessedTime":"2017-11-16T08:19:21Z","path":"/concurrent_users.htm"},{"lastAccessedTime":"2017-11-16T08:20:13Z","path":"/concurrent_users.htm"},{"lastAccessedTime":"2017-11-16T08:20:59Z","path":"/concurrent_users.htm"},{"lastAccessedTime":"2017-11-16T08:22:59Z","path":"/concurrent_users.htm"},{"lastAccessedTime":"2017-11-16T08:25:14Z","path":"/concurrent_users.htm"},{"lastAccessedTime":"2017-11-16T08:26:17Z","path":"/concurrent_users.htm"},{"id":913,"cookieId":"WfP2r2jiq4xAKo9YziaV5winTllwY5HL","creationTime":"2017-11-16T08:47:15Z","lastAccessedTime":"2017-11-16T08:47:15Z","path":"/login.htm"},{"lastAccessedTime":"2017-11-16T08:49:47Z","path":"/concurrent_users.htm"},{"lastAccessedTime":"2017-11-16T09:12:39Z","path":"/concurrent_users.htm"},{"lastAccessedTime":"2017-11-16T09:24:25Z","path":"/login.htm"},{"lastAccessedTime":"2017-11-16T09:26:15Z","path":"/concurrent_users.htm"},{"lastAccessedTime":"2017-11-16T09:28:10Z","path":"/concurrent_users.htm"},{"lastAccessedTime":"2017-11-16T09:28:53Z","path":"/concurrent_users.htm"},{"lastAccessedTime":"2017-11-16T09:30:49Z","path":"/concurrent_users.htm"},{"lastAccessedTime":"2017-11-16T09:31:48Z","path":"/concurrent_users.htm"},{"lastAccessedTime":"2017-11-16T09:34:01Z","path":"/concurrent_users.htm"},{"lastAccessedTime":"2017-11-16T09:43:47Z","path":"/concurrent_users.htm"},{"lastAccessedTime":"2017-11-16T09:44:21Z","path":"/concurrent_users.htm"},{"lastAccessedTime":"2017-11-16T09:44:30Z","path":"/login.htm"},{"lastAccessedTime":"2017-11-16T09:44:34Z","path":"/concurrent_users.htm"},{"lastAccessedTime":"2017-11-16T09:44:48Z","path":"/"},{"lastAccessedTime":"2017-11-16T09:44:54Z","path":"/login.htm"},{"lastAccessedTime":"2017-11-16T09:44:56Z","path":"/concurrent_users.htm"},{"lastAccessedTime":"2017-11-16T09:45:09Z","path":"/"},{"lastAccessedTime":"2017-11-16T09:45:14Z","path":"/login.htm"},{"lastAccessedTime":"2017-11-16T09:45:16Z","path":"/concurrent_users.htm"},{"lastAccessedTime":"2017-11-16T09:45:30Z","path":"/"},{"lastAccessedTime":"2017-11-16T09:45:35Z","path":"/login.htm"},{"lastAccessedTime":"2017-11-16T09:45:38Z","path":"/concurrent_users.htm"},{"lastAccessedTime":"2017-11-16T09:49:31Z","path":"/settings/license.htm"},{"lastAccessedTime":"2017-11-16T09:50:47Z","path":"/concurrent_users.htm"},{"lastAccessedTime":"2017-11-16T09:50:57Z","path":"/concurrent_users.htm"},{"lastAccessedTime":"2017-11-16T09:51:32Z","path":"/settings/license.htm"},{"lastAccessedTime":"2017-11-16T09:52:06Z","path":"/concurrent_users.htm"},{"lastAccessedTime":"2017-11-16T09:58:55Z","path":"/concurrent_users.htm"},{"lastAccessedTime":"2017-11-16T09:59:12Z","path":"/connections/qc.htm"},{"lastAccessedTime":"2017-11-16T09:59:22Z","path":"/connections/rally.htm"},{"lastAccessedTime":"2017-11-16T10:07:10Z","path":"/connections/rally.htm"},{"lastAccessedTime":"2017-11-16T10:11:21Z","path":"/connections/rally.htm"},{"lastAccessedTime":"2017-11-16T10:22:48Z","path":"/connections/rally.htm"},{"lastAccessedTime":"2017-11-16T10:30:27Z","path":"/connections/rally.htm"},{"lastAccessedTime":"2017-11-16T10:34:10Z","path":"/connections/rally.htm"}];

const prepareData = (data) => {
  const sortedData = [];
  const startDate = [];
  const endDate = [];
  // transform GMT to local time
  data.forEach(d => {
    d.lastAccessedTime = moment(d.lastAccessedTime).format('YYYY-MM-DD HH:mm:ss');
  });
  // sort dates in ascending order
  data.sort((a, b) => moment(a.lastAccessedTime) - moment(b.lastAccessedTime));

  data.forEach(d => {
    const start = moment(d.lastAccessedTime);
    let put = sortedData;
    let endMinutes;
    let startMinutes;

    if (start.minute() < 30) {
      endMinutes = 30 - start.minute();
      startMinutes = -start.minute();
    } else {
      endMinutes = 60 - start.minute();
      startMinutes = 30 - start.minute();
    };

    const startTime = moment(start)
      .add(startMinutes, 'minutes')
      .add(-start.seconds(), 'seconds')
      .format('YYYY-MM-DD HH:mm:ss');

    const endTime = moment(start)
      .add(endMinutes, 'minutes')
      .add(-start.seconds(), 'seconds')
      .format('YYYY-MM-DD HH:mm:ss');

    sortedData.forEach(itm2 => {
      itm2.forEach(itm3 => {
        const date = moment(itm3.lastAccessedTime);
        const min = moment(startTime);
        const max = moment(endTime);
        if (date < max && date > min) {
          put = itm2;
        }
      });
    });

    if (put === sortedData) {
      startDate.push(startTime);
      endDate.push(endTime);
      put.push([d]);
    } else {
      put.push(d);
    };
  });

  const preparedData = sortedData.map((data, i) => {
    const object = {
      startDate: startDate[i],
      endDate: endDate[i]
    };
    return object;
  });
  console.log(JSON.stringify(sortedData));
  console.log(JSON.stringify(preparedData));
};
prepareData(data);

【问题讨论】:

  • 请添加一个想要的结果的小例子。
  • 当前结果是想要的结果。尝试用更少的代码行 + 更快的速度达到相同的结果
  • 在小提琴中你可以看到两个 console.log 输出

标签: javascript sorting optimization momentjs


【解决方案1】:

您可以使用ISO 8601 日期字符串对数组进行排序,并使用哈希表对同一时间段进行分组。

var array = [{ lastAccessedTime: "2017-11-16T07:15:41Z", path: "/login.htm" }, { lastAccessedTime: "2017-11-16T07:32:42Z", path: "/login.htm" }, { lastAccessedTime: "2017-11-16T07:32:47Z", path: "/concurrent_users.htm" }, { lastAccessedTime: "2017-11-16T07:36:02Z", path: "/concurrent_users.htm" }, { lastAccessedTime: "2017-11-16T07:36:55Z", path: "/concurrent_users.htm" }, { lastAccessedTime: "2017-11-16T07:37:28Z", path: "/concurrent_users.htm" }, { lastAccessedTime: "2017-11-16T07:39:48Z", path: "/concurrent_users.htm" }, { lastAccessedTime: "2017-11-16T07:40:47Z", path: "/concurrent_users.htm" }, { lastAccessedTime: "2017-11-16T07:42:31Z", path: "/concurrent_users.htm" }, { lastAccessedTime: "2017-11-16T07:44:06Z", path: "/concurrent_users.htm" }, { lastAccessedTime: "2017-11-16T07:46:04Z", path: "/concurrent_users.htm" }, { lastAccessedTime: "2017-11-16T07:46:43Z", path: "/concurrent_users.htm" }, { lastAccessedTime: "2017-11-16T07:50:31Z", path: "/concurrent_users.htm" }, { lastAccessedTime: "2017-11-16T07:52:54Z", path: "/concurrent_users.htm" }, { lastAccessedTime: "2017-11-16T07:53:53Z", path: "/concurrent_users.htm" }, { lastAccessedTime: "2017-11-16T08:14:00Z", path: "/concurrent_users.htm" }, { lastAccessedTime: "2017-11-16T08:14:44Z", path: "/concurrent_users.htm" }, { lastAccessedTime: "2017-11-16T08:16:20Z", path: "/concurrent_users.htm" }, { lastAccessedTime: "2017-11-16T08:17:32Z", path: "/concurrent_users.htm" }, { lastAccessedTime: "2017-11-16T08:19:21Z", path: "/concurrent_users.htm" }, { lastAccessedTime: "2017-11-16T08:20:13Z", path: "/concurrent_users.htm" }, { lastAccessedTime: "2017-11-16T08:20:59Z", path: "/concurrent_users.htm" }, { lastAccessedTime: "2017-11-16T08:22:59Z", path: "/concurrent_users.htm" }, { lastAccessedTime: "2017-11-16T08:25:14Z", path: "/concurrent_users.htm" }, { lastAccessedTime: "2017-11-16T08:26:17Z", path: "/concurrent_users.htm" }, { id: 913, cookieId: "WfP2r2jiq4xAKo9YziaV5winTllwY5HL", creationTime: "2017-11-16T08:47:15Z", lastAccessedTime: "2017-11-16T08:47:15Z", path: "/login.htm" }, { lastAccessedTime: "2017-11-16T08:49:47Z", path: "/concurrent_users.htm" }, { lastAccessedTime: "2017-11-16T09:12:39Z", path: "/concurrent_users.htm" }, { lastAccessedTime: "2017-11-16T09:24:25Z", path: "/login.htm" }, { lastAccessedTime: "2017-11-16T09:26:15Z", path: "/concurrent_users.htm" }, { lastAccessedTime: "2017-11-16T09:28:10Z", path: "/concurrent_users.htm" }, { lastAccessedTime: "2017-11-16T09:28:53Z", path: "/concurrent_users.htm" }, { lastAccessedTime: "2017-11-16T09:30:49Z", path: "/concurrent_users.htm" }, { lastAccessedTime: "2017-11-16T09:31:48Z", path: "/concurrent_users.htm" }, { lastAccessedTime: "2017-11-16T09:34:01Z", path: "/concurrent_users.htm" }, { lastAccessedTime: "2017-11-16T09:43:47Z", path: "/concurrent_users.htm" }, { lastAccessedTime: "2017-11-16T09:44:21Z", path: "/concurrent_users.htm" }, { lastAccessedTime: "2017-11-16T09:44:30Z", path: "/login.htm" }, { lastAccessedTime: "2017-11-16T09:44:34Z", path: "/concurrent_users.htm" }, { lastAccessedTime: "2017-11-16T09:44:48Z", path: "/" }, { lastAccessedTime: "2017-11-16T09:44:54Z", path: "/login.htm" }, { lastAccessedTime: "2017-11-16T09:44:56Z", path: "/concurrent_users.htm" }, { lastAccessedTime: "2017-11-16T09:45:09Z", path: "/" }, { lastAccessedTime: "2017-11-16T09:45:14Z", path: "/login.htm" }, { lastAccessedTime: "2017-11-16T09:45:16Z", path: "/concurrent_users.htm" }, { lastAccessedTime: "2017-11-16T09:45:30Z", path: "/" }, { lastAccessedTime: "2017-11-16T09:45:35Z", path: "/login.htm" }, { lastAccessedTime: "2017-11-16T09:45:38Z", path: "/concurrent_users.htm" }, { lastAccessedTime: "2017-11-16T09:49:31Z", path: "/settings/license.htm" }, { lastAccessedTime: "2017-11-16T09:50:47Z", path: "/concurrent_users.htm" }, { lastAccessedTime: "2017-11-16T09:50:57Z", path: "/concurrent_users.htm" }, { lastAccessedTime: "2017-11-16T09:51:32Z", path: "/settings/license.htm" }, { lastAccessedTime: "2017-11-16T09:52:06Z", path: "/concurrent_users.htm" }, { lastAccessedTime: "2017-11-16T09:58:55Z", path: "/concurrent_users.htm" }, { lastAccessedTime: "2017-11-16T09:59:12Z", path: "/connections/qc.htm" }, { lastAccessedTime: "2017-11-16T09:59:22Z", path: "/connections/rally.htm" }, { lastAccessedTime: "2017-11-16T10:07:10Z", path: "/connections/rally.htm" }, { lastAccessedTime: "2017-11-16T10:11:21Z", path: "/connections/rally.htm" }, { lastAccessedTime: "2017-11-16T10:22:48Z", path: "/connections/rally.htm" }, { lastAccessedTime: "2017-11-16T10:30:27Z", path: "/connections/rally.htm" }, { lastAccessedTime: "2017-11-16T10:34:10Z", path: "/connections/rally.htm" }],
    groups = Object.create(null),
    result = [];

array.sort((a, b) => a.lastAccessedTime > b.lastAccessedTime || -(a.lastAccessedTime < b.lastAccessedTime));

array.forEach(function (o) {
    var slot = Math.floor(o.lastAccessedTime.slice(14, 16) / 30),
        key = o.lastAccessedTime.slice(0, 14) + (slot ? '30' : '00');
    if (!groups[key]) {
        groups[key] = [];
        result.push(groups[key]);
    }
    groups[key].push(o);
});

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

【讨论】:

    【解决方案2】:

    优化方式:

    1/ 尝试删除时刻并改用日期函数。

    2/ 尝试删除/更改循环内循环:

     data.forEach(d => {
        ....
        sortedData.forEach(itm2 => {
           itm2.forEach(itm3 => {
               ....
           });
        });
     });
    

    【讨论】:

    • 移除时刻不是一种选择(潜在客户政策)。我对 `the loop inside loop inside loop` 也不满意,但不确定我尝试过的任何东西都不会给我同样的结果。
    • 我只通过删除时刻(10000 循环的 10 毫秒对 140 毫秒,请参阅 pastebin.com/puWhbnQgpastebin.com/Pez5zhWr )获得快 14 的结果。但主要问题是循环重叠
    猜你喜欢
    • 2010-10-15
    • 1970-01-01
    • 1970-01-01
    • 2018-10-08
    • 2015-11-09
    • 1970-01-01
    • 2012-04-07
    • 1970-01-01
    相关资源
    最近更新 更多