【问题标题】:JavaScript - Array Slicing: based on a filter for different rangeJavaScript - 数组切片:基于不同范围的过滤器
【发布时间】:2020-06-23 14:25:18
【问题描述】:

我有一个对象数组如下:

数组:

[
  {
    "isChecked": false,
    "title": "00:00"
  },
  {
    "isChecked": false,
    "title": "00:30"
  },
  {
    "isChecked": false,
    "title": "01:00"
  },
  {
    "isChecked": false,
    "title": "01:30"
  },
  {
    "isChecked": false,
    "title": "02:00"
  },
  {
    "isChecked": false,
    "title": "02:30"
  },
  {
    "isChecked": false,
    "title": "03:00"
  },
  {
    "isChecked": false,
    "title": "03:30"
  },
  {
    "isChecked": false,
    "title": "04:00"
  },
  {
    "isChecked": false,
    "title": "04:30"
  },
  {
    "isChecked": false,
    "title": "05:00"
  },
  {
    "isChecked": false,
    "title": "05:30"
  },
  {
    "isChecked": false,
    "title": "06:00"
  },
  {
    "isChecked": false,
    "title": "06:30"
  },
  {
    "isChecked": false,
    "title": "07:00"
  },
  {
    "isChecked": false,
    "title": "07:30"
  },
  {
    "isChecked": false,
    "title": "08:00"
  },
  {
    "isChecked": false,
    "title": "08:30"
  },
  {
    "isChecked": false,
    "title": "09:00"
  },
  {
    "isChecked": false,
    "title": "09:30"
  },
  {
    "isChecked": false,
    "title": "10:00"
  },
  {
    "isChecked": false,
    "title": "10:30"
  },
  {
    "isChecked": false,
    "title": "11:00"
  },
  {
    "isChecked": false,
    "title": "11:30"
  }
]

用户界面:显示如下:

用户操作:当用户选择任何时间段时,如下所示:

然后数组会有一些检查时间。

[
  {
    "isChecked": true,
    "title": "00:00"
  },
  {
    "isChecked": true,
    "title": "00:30"
  },
  {
    "isChecked": true,
    "title": "01:00"
  },
  {
    "isChecked": true,
    "title": "01:30"
  },
  {
    "isChecked": true,
    "title": "02:00"
  },
  {
    "isChecked": false,
    "title": "02:30"
  },
  {
    "isChecked": false,
    "title": "03:00"
  },
  {
    "isChecked": false,
    "title": "03:30"
  },
  {
    "isChecked": false,
    "title": "04:00"
  },
  {
    "isChecked": false,
    "title": "04:30"
  },
  {
    "isChecked": false,
    "title": "05:00"
  },
  {
    "isChecked": false,
    "title": "05:30"
  },
  {
    "isChecked": false,
    "title": "06:00"
  },
  {
    "isChecked": false,
    "title": "06:30"
  },
  {
    "isChecked": true,
    "title": "07:00"
  },
  {
    "isChecked": true,
    "title": "07:30"
  },
  {
    "isChecked": true,
    "title": "08:00"
  },
  {
    "isChecked": true,
    "title": "08:30"
  },
  {
    "isChecked": true,
    "title": "09:00"
  },
  {
    "isChecked": false,
    "title": "09:30"
  },
  {
    "isChecked": true,
    "title": "10:00"
  },
  {
    "isChecked": true,
    "title": "10:30"
  },
  {
    "isChecked": true,
    "title": "11:00"
  },
  {
    "isChecked": false,
    "title": "11:30"
  }
]

我想要什么:所有时间会话的列表(从开始到结束),基于选定的时间段:

输出:

[
  {
    "StartTime": "00:00",
    "EndTime": "02:00"
  },
{
    "StartTime": "07:00",
    "EndTime": "09:00"
  },
{
    "StartTime": "10:00",
    "EndTime": "11:00"
  },
]

我已经尝试了一点,但没有得到想要的输出。

这是我的代码的链接 https://stackblitz.com/edit/ngoninit-wvnjfk

我们将非常感谢您的帮助!

【问题讨论】:

  • 所以你正在尝试使用你必须创建一个连续时间块列表的设计?此外,您的示例数据应该是:00:00 -> 02:30 等。您检查了 2:00 块,因此这意味着消耗了 30 分钟块,因此您的所有项目范围都应该位于底部小时(第一个空块的顶部)

标签: javascript arrays slice


【解决方案1】:

您可以检查插槽和前任并添加新对象或更新最后一个对象。

var data = [{ isChecked: true, title: "00:00" }, { isChecked: true, title: "00:30" }, { isChecked: true, title: "01:00" }, { isChecked: true, title: "01:30" }, { isChecked: true, title: "02:00" }, { isChecked: false, title: "02:30" }, { isChecked: false, title: "03:00" }, { isChecked: false, title: "03:30" }, { isChecked: false, title: "04:00" }, { isChecked: false, title: "04:30" }, { isChecked: false, title: "05:00" }, { isChecked: false, title: "05:30" }, { isChecked: false, title: "06:00" }, { isChecked: false, title: "06:30" }, { isChecked: true, title: "07:00" }, { isChecked: true, title: "07:30" }, { isChecked: true, title: "08:00" }, { isChecked: true, title: "08:30" }, { isChecked: true, title: "09:00" }, { isChecked: false, title: "09:30" }, { isChecked: true, title: "10:00" }, { isChecked: true, title: "10:30" }, { isChecked: true, title: "11:00" }, { isChecked: false, title: "11:30" }],
    result = data.reduce((r, { isChecked, title }, i, a) => {
        if (!isChecked) return r;

        if (!i || !a[i - 1].isChecked) r.push({ StartTime: title, EndTime: title });
        else r[r.length - 1].EndTime = title;

        return r;
    }, []);         

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

【讨论】:

  • 谢谢@Nina Scholz
【解决方案2】:

使用js reduce的解决方案。块数组然后取第一次和最后一次。

const data=[{"isChecked":!0,"title":"00:00"},{"isChecked":!0,"title":"00:30"},{"isChecked":!0,"title":"01:00"},{"isChecked":!0,"title":"01:30"},{"isChecked":!0,"title":"02:00"},{"isChecked":!1,"title":"02:30"},{"isChecked":!1,"title":"03:00"},{"isChecked":!1,"title":"03:30"},{"isChecked":!1,"title":"04:00"},{"isChecked":!1,"title":"04:30"},{"isChecked":!1,"title":"05:00"},{"isChecked":!1,"title":"05:30"},{"isChecked":!1,"title":"06:00"},{"isChecked":!1,"title":"06:30"},{"isChecked":!0,"title":"07:00"},{"isChecked":!0,"title":"07:30"},{"isChecked":!0,"title":"08:00"},{"isChecked":!0,"title":"08:30"},{"isChecked":!0,"title":"09:00"},{"isChecked":!1,"title":"09:30"},{"isChecked":!0,"title":"10:00"},{"isChecked":!0,"title":"10:30"},{"isChecked":!0,"title":"11:00"},{"isChecked":!1,"title":"11:30"}];

const result = data.reduce(({ curr, times }, n) => {
    if (curr != n.isChecked && n.isChecked) times.push([]);
    if (n.isChecked) times[times.length-1].push(n.title);
    return { curr: n.isChecked, times };
}, { curr: false, times: [] }).times.map(range => ({ StartTime: range[0], EndTime: range[range.length-1] }));

console.log(result);

【讨论】:

    【解决方案3】:

    您可以减少时隙数据集,并根据当前和以前的时隙返回时间块。

    1. 只要检查isChecked 并添加一个新块,如果之前的槽没有被检查。
    2. 如果当前未选中,但前一个已选中,则完成时间块。

    const expected = getExpected(),
          actual   = calculateTimeBlocks(getInput());
    
    console.log('Equal?:', JSON.stringify(actual) === JSON.stringify(expected));
    console.log(actual);
    
    function calculateTimeBlocks(timeSlots) {  
      return timeSlots.reduce((blocks, curr, index, arr) => {
        let prev = index > 0 ? arr[index - 1] : null;
        if (curr.isChecked) {
          if (!prev || !prev.isChecked) {
            blocks.push({ "StartTime" : curr.title });
          }
        } else {
          if (prev && prev.isChecked) {
            Object.assign(blocks[blocks.length - 1], {
              ["EndTime"] : prev.title
            });
          }
        }
        return blocks;
      }, []);
    }
    
    function getInput() {
      return [
        { "isChecked": true,  "title": "00:00" },
        { "isChecked": true,  "title": "00:30" },
        { "isChecked": true,  "title": "01:00" },
        { "isChecked": true,  "title": "01:30" },
        { "isChecked": true,  "title": "02:00" },
        { "isChecked": false, "title": "02:30" },
        { "isChecked": false, "title": "03:00" },
        { "isChecked": false, "title": "03:30" },
        { "isChecked": false, "title": "04:00" },
        { "isChecked": false, "title": "04:30" },
        { "isChecked": false, "title": "05:00" },
        { "isChecked": false, "title": "05:30" },
        { "isChecked": false, "title": "06:00" },
        { "isChecked": false, "title": "06:30" },
        { "isChecked": true,  "title": "07:00" },
        { "isChecked": true,  "title": "07:30" },
        { "isChecked": true,  "title": "08:00" },
        { "isChecked": true,  "title": "08:30" },
        { "isChecked": true,  "title": "09:00" },
        { "isChecked": false, "title": "09:30" },
        { "isChecked": true,  "title": "10:00" },
        { "isChecked": true,  "title": "10:30" },
        { "isChecked": true,  "title": "11:00" },
        { "isChecked": false, "title": "11:30" }
      ];
    }
    
    function getExpected() {
      return [
        { "StartTime": "00:00", "EndTime": "02:00" },
        { "StartTime": "07:00", "EndTime": "09:00" },
        { "StartTime": "10:00", "EndTime": "11:00" },
      ];
    }
    .as-console-wrapper { top: 0; max-height: 100% !important; }

    【讨论】:

      猜你喜欢
      • 2015-09-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-10-18
      • 2019-01-16
      • 2014-11-27
      • 1970-01-01
      相关资源
      最近更新 更多