Разбивка доступного массива временных интервалов на куски на основе забронированных слотов - PullRequest
1 голос
/ 05 июня 2019

У меня есть 2 массива:

  1. сгенерированных временных меток (30 минут каждая (1800 difference in each timestamp)) от определенного начального часа до конечного часа дня.
  2. Я получаю ответ забронированных слотов от ответа API.

Мне нужно объединить оба массива, чтобы сформировать массив объектов, представляющих доступные и забронированные слоты:

let availableTimeslots = [
  1559709000,
  1559710800,
  1559712600,
  1559714400,
  1559716200,
  1559718000,
  1559719800,
  1559721600,
  1559723400,
  1559725200,
  1559727000,
  1559728800,
  1559730600,
  1559732400,
  1559734200,
  1559736000,
  1559737800,
  1559739600
];

let bookedTimeSlots = {
  bookings: [
    {
      timestamp: {
        from: 1559719800,
        to: 1559723400
      }
    },
    {
      timestamp: {
        from: 1559730600,
        to: 1559732400
      }
    }
  ]
};

Мне нужно создать массив объектов, что-то вроде:

[
  {
    available: true,
    timeslots: [1559709000, 1559710800, 1559712600, 1559714400, 1559716200, 1559718000]
  },
  {
    available: false,
    timeslots: [1559719800, 1559721600, 1559723400]
  },
  {
    available: true,
    timeslots: [1559725200, 1559727000, 1559728800]
  },
  {
    available: false,
    timeslots: [1559730600, 1559732400]
  },
  {
    available: true,
    timeslots: [1559732400, 1559734200, 1559736000, 1559737800, 1559739600]
  }
];

Я действительно запутался, как поступить с этим, я думаю озамените значение в availableTimeslots на желаемый объект забронированного слота, а затем на все значения, не связанные с объектом, на {available: true, timeslots: [...]}

bookedTimeSlots.bookings.map((bs, i)=> {
            let ai = availableTimeslots.findIndex(bs.timestamp.from);
            ai > -1 && (availableTimeslots[ai]={available: false, x  : [..._.range(bs.timestamp.from, bs.timestamp.to, 1800)]});
        })

. Любая помощь будет принята.

Ответы [ 2 ]

1 голос
/ 05 июня 2019

Существует множество способов решить эту проблему.Один из способов упростить его - воспользоваться тем, что между временными интервалами есть известное приращение (1800), поэтому вместо того, чтобы пытаться нарезать массив временных интервалов, вы можете сгенерировать новый массив временных интервалов для каждого «чанка» при запускеи конец временного интервала.В следующем фрагменте вы можете увидеть базовое рекурсивное решение, которое использует этот подход:

const INCREMENT = 1800;

// Utility function to generate an inclusive range
function rangeIncl(start, end, incr = INCREMENT) {
  return start < end ? [start, ...rangeIncl(start + incr, end)] : [end];
}

function timeslotGroups(startTimeslot, endTimeslot, bookings) {
  const [booking, ...restBookings] = bookings;

  if (booking) {
    if (startTimeslot < booking.from) {
      // startTimeslot is before next booking.from; add available group
      return [
        {
          available: true,
          timeslots: rangeIncl(startTimeslot, booking.from - INCREMENT),
        },
        ...timeslotGroups(booking.from, endTimeslot, bookings),
      ];
    }

    if (startTimeslot <= booking.to) {
      // startTimeslot is between booking.from and .to; add not-available group
      return [
        {
          available: false,
          timeslots: rangeIncl(booking.from, booking.to),
        },
        ...timeslotGroups(booking.to + INCREMENT, endTimeslot, restBookings),
      ];
    }

    // startTimeslot is after booking.to; try again with next booking
    return timeslotGroups(startTimeslot, endTimeslot, restBookings);
  }
  
  // No more bookings; add final available group if there are any
  // timeslots left
  return startTimeslot < endTimeslot ? [
    {
      available: true,
      timeslots: rangeIncl(startTimeslot, endTimeslot),
    },
  ] : [];
}

const availableTimeslots = [
  1559709000, 1559710800, 1559712600, 1559714400, 1559716200, 1559718000,
  1559719800, 1559721600, 1559723400, 1559725200, 1559727000, 1559728800,
  1559730600, 1559732400, 1559734200, 1559736000, 1559737800, 1559739600,
];

const bookedTimeslots = {
  bookings: [
    { timestamp: { from: 1559719800, to: 1559723400 }},
    { timestamp: { from: 1559730600, to: 1559732400 }},
  ],
};

const firstTimeslot = availableTimeslots[0];
const lastTimeslot = availableTimeslots[availableTimeslots.length - 1];
// Bookings will be easier to work with as an array of { from, to } objects
const bookings = bookedTimeslots.bookings.map(booking => booking.
timestamp);

const groups = timeslotGroups(firstTimeslot, lastTimeslot, bookings);
console.log(groups);

Обратите внимание, что в этом коде предполагается, что bookings будет в хронологическом порядке.

0 голосов
/ 05 июня 2019

Я сделал это примерно так: https://jsfiddle.net/saurabhsharma/a6qoyfhd/

let availableTimeslots = [
    1559709000,
    1559710800,
    1559712600,
    1559714400,
    1559716200,
    1559718000,
    1559719800,
    1559721600,
    1559723400,
    1559725200,
    1559727000,
    1559728800,
    1559730600,
    1559732400,
    1559734200,
    1559736000,
    1559737800,
    1559739600
];

let parsedArr = [];

let bookedTimeSlots = {
    bookings: [{
            timestamp: {
                from: 1559719800,
                to: 1559723400
            }
        },
        {
            timestamp: {
                from: 1559730600,
                to: 1559732400
            }
        }
    ]
};


/* parsedArr = availableTimeslots.map((ts, i) => {
    return bookedTimeSlots.bookings.map((bs, n)=> {
        let x = [];
        if(ts<bs.timestamp.from) {
            x.push(ts);
        } else { return {available: true, timeslots: [...x]}}
    })
}) */


bookedTimeSlots.bookings.map((bs, i) => {
    let ai = availableTimeslots.indexOf(bs.timestamp.from);
    if (ai > -1) {
        let range = [..._.range(bs.timestamp.from, bs.timestamp.to, 1800)]
        availableTimeslots[ai] = {
            available: false,
            timestamp: [...range]
        };
        availableTimeslots.splice(ai + 1, range.length - 1);
    }
})

console.log("availableTimeSlot", availableTimeslots);

let tempArr = [];
let startIndex = '';
let timeStampParsed = [...availableTimeslots];

while(!timeStampParsed.every((ts)=>typeof ts == 'object')) {
	timeStampParsed.map((ts, i) => {
        if (typeof ts != "object") {
            tempArr.push(ts);
            startIndex === '' && (startIndex = i);
            //Case i reached the last index
            if (i == timeStampParsed.length - 1) {
                let range = [..._.range(timeStampParsed[startIndex], timeStampParsed[i]+1800, 1800)];
                console.log(range);
                timeStampParsed[startIndex] = {
                    available: true,
                    timestamp: [...range]
                };
                timeStampParsed.splice(startIndex + 1, range.length);
                tempArr = [];
                startIndex = '';
            }
        } else {
            if (tempArr.length > 0 && startIndex !== '') {
                let range = [..._.range(timeStampParsed[startIndex], timeStampParsed[i-1], 1800)];
                timeStampParsed[startIndex] = {
                    available: true,
                    timestamp: [...range]
                };
                timeStampParsed.splice(startIndex+1, range.length);
                tempArr = [];
                startIndex = '';
            }
        }
    })
}

console.log("TIMESTAMP PARSED =>", timeStampParsed);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.min.js"></script>

Пожалуйста, предложите лучший способ сделать это.

...