JavaScript - Нарезка массива: на основе фильтра для другого диапазона - PullRequest
3 голосов
/ 11 марта 2020

У меня есть массив объектов следующим образом:

Массив:

[
  {
    "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"
  }
]

Пользовательский интерфейс: Отображается так:

enter image description here

Действие пользователя: Когда пользователь выбирает любые временные интервалы, например: enter image description here

Массив будет иметь некоторое проверенное время.

[
  {
    "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

Ваша помощь будет высоко оценена!

Ответы [ 3 ]

1 голос
/ 11 марта 2020

Вы можете проверить слот и предшественника и добавить новый объект или обновить последний объект.

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; }
0 голосов
/ 11 марта 2020

Вы можете уменьшить набор данных временного интервала и блоки времени возврата, основываясь на текущем и предыдущем временных интервалах.

  1. Просто проверьте isChecked и добавьте новый блок, если предыдущий интервал не был проверено.
  2. Если текущий не проверен, а предыдущий был, то конечный sh блок времени.

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; }
0 голосов
/ 11 марта 2020

Решение с использованием js уменьшить. Затем массив массива берут первый и последний раз.

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);
...