Учитывая массив объектов, представляющих пути транспортного средства, отсортированные по дате, какой способ объединения последовательных элементов является наиболее эффективным, если:

  • start_location_in_zone и end_location_in_zone истинны
  • start_location_in_zone и end_location_in_zone оба ложны

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

  • start_date = начальная_дата первого объединенного элемента
  • end_date = end_date последнего объединенного элемента
  • продолжительность = сумма всей продолжительности слияния
  • start_index = индекс первого объединенного элемента в старом массиве
  • end_index = индекс последнего объединенного элемента в старом массиве
  • state = "out_zone", если оба ложны
  • state = "in_zone", если оба верны

Если элемент имеет start_location_in_zone и end_location_in_zone с другим логическим значением:

  • мы сохраняем это (без слияния)
  • start_index и end_index = индекс в старом массиве
  • state = "to_zone" если (start_location_in_zone == false и end_location_in_zone == true)
  • state = "from_zone" если (start_location_in_zone == true и end_location_in_zone == false)

Пример :

[
    {
        "start_date": "2020-10-07T13:53:26.000",
        "end_date": "2020-10-07T14:55:49.000",
        "start_location_in_zone": false,
        "end_location_in_zone": false,
        "duration": 143000
    },
    {
        "start_date": "2020-10-07T15:53:26.000",
        "end_date": "2020-10-07T16:55:49.000",
        "start_location_in_zone": false,
        "end_location_in_zone": true,
        "duration": 7000
    },
    {
        "start_date": "2020-10-07T17:53:26.000",
        "end_date": "2020-10-07T18:55:49.000",
        "start_location_in_zone": true,
        "end_location_in_zone": true,
        "duration": 20000
    },
    {
        "start_date": "2020-10-07T19:53:26.000",
        "end_date": "2020-10-07T20:55:49.000",
        "start_location_in_zone": true,
        "end_location_in_zone": true,
        "duration": 30000
    },
    {
        "start_date": "2020-10-07T21:53:26.000",
        "end_date": "2020-10-07T22:55:49.000",
        "start_location_in_zone": false,
        "end_location_in_zone": false,
        "duration": 4200
    },
    {
        "start_date": "2020-10-07T23:53:26.000",
        "end_date": "2020-10-08T00:00:49.000",
        "start_location_in_zone": false,
        "end_location_in_zone": false,
        "duration": 4200
    }
]

Результат:

[{
    "start_date": "2020-10-07T13:53:26.000",
    "end_date": "2020-10-07T14:55:49.000",
    "state": "out_zone",
    "duration": 143000,
    "start_index": "0",
    "end_index": "0"
  },
  {
    "start_date": "2020-10-07T15:53:26.000",
    "end_date": "2020-10-07T16:55:49.000",
    "state": "to_zone",
    "duration": 7000,
    "start_index": "1",
    "end_index": "1"
  },
  {
    "start_date": "2020-10-07T17:53:26.000",
    "end_date": "2020-10-07T19:55:49.000",
    "state": "in_zone",
    "duration": 50000,
    "start_index": "2",
    "end_index": "3"
  },
  {
    "start_date": "2020-10-07T21:53:26.000",
    "end_date": "2020-10-08T00:10:49.000",
    "state": "out_zone",
    "duration": 8400,
    "start_index": "4",
    "end_index": "5"
  }
]
1
Amine Da. 6 Дек 2020 в 00:52

1 ответ

Лучший ответ

Хороший случай для Reduce.

const data = [
  {
    "start_date": "2020-10-07T13:53:26.000",
    "end_date": "2020-10-07T14:55:49.000",
    "start_location_in_zone": false,
    "end_location_in_zone": false,
    "duration": 143000
  },
  {
    "start_date": "2020-10-07T15:53:26.000",
    "end_date": "2020-10-07T16:55:49.000",
    "start_location_in_zone": false,
    "end_location_in_zone": true,
    "duration": 7000
  },
  {
    "start_date": "2020-10-07T17:53:26.000",
    "end_date": "2020-10-07T18:55:49.000",
    "start_location_in_zone": true,
    "end_location_in_zone": true,
    "duration": 20000
  },
  {
    "start_date": "2020-10-07T19:53:26.000",
    "end_date": "2020-10-07T20:55:49.000",
    "start_location_in_zone": true,
    "end_location_in_zone": true,
    "duration": 30000
  },
  {
    "start_date": "2020-10-07T21:53:26.000",
    "end_date": "2020-10-07T22:55:49.000",
    "start_location_in_zone": false,
    "end_location_in_zone": false,
    "duration": 4200
  },
  {
    "start_date": "2020-10-07T23:53:26.000",
    "end_date": "2020-10-08T00:00:49.000",
    "start_location_in_zone": false,
    "end_location_in_zone": false,
    "duration": 4200
  },
  {
    "start_date": "2020-10-08T00:00:49.000",
    "end_date": "2020-10-08T00:00:50.000",
    "start_location_in_zone": false,
    "end_location_in_zone": false,
    "duration": 1
  },
  {
    "start_date": "2020-10-08T00:00:50.000",
    "end_date": "2020-10-08T00:00:51.000",
    "start_location_in_zone": false,
    "end_location_in_zone": false,
    "duration": 2
  },
  {
    "start_date": "2020-10-08T00:00:51.000",
    "end_date": "2020-10-08T00:00:52.000",
    "start_location_in_zone": false,
    "end_location_in_zone": true,
    "duration": 12
  }
]


let previous = undefined
let mergedData = data.reduce((acc, cur, i) => {
  cur.start_index = i
  cur.end_index = i
  if (!previous) {
    previous = cur
    return acc
  }
  let isStartInZone  = previous.start_location_in_zone === previous.end_location_in_zone
  let isEndNotInZone = cur.start_location_in_zone === cur.end_location_in_zone
  let shouldMerge = isStartInZone && isEndNotInZone && previous.start_location_in_zone === cur.start_location_in_zone
  if (shouldMerge) {
    previous.end_date = cur.end_date
    previous.duration += cur.duration
    previous.end_index = i
    //acc.push(previous)
    //previous = undefined
    return acc
  }
  acc.push(previous)
  previous = cur
  return acc
}, [])
// handle left overs if last element is not merged
if (previous) mergedData.push(previous)
console.log(mergedData)
1
Michael Hobbs 7 Дек 2020 в 14:53