Как создать массив объектов в порядке отметок времени на основе максимального и минимального значений? - PullRequest
0 голосов
/ 28 мая 2020

Пытаюсь найти лучший способ создать массив объектов, в котором я получаю только максимальное и минимальное значения два раза в день (до 12:00 и после 12:00). Результат должен возвращаться в порядке времени.

Лучший способ, который я знаю, это сделать:

  1. Сначала отфильтруйте данные по дню (я использую момент. js)
  2. Затем отфильтруйте день в 2 разных массива: beforeNoon [], afterNoon []
  3. Затем получите максимальное значение массивов с помощью reduce
  4. Затем получите Минимальное значение массивов с помощью команды reduce
  5. Объедините результаты в 1 массив и отсортируйте по возрастанию

Я надеялся, что будет гораздо более простой способ сделать это .. дайте мне знать, если у вас есть предложения. Заранее благодарим за любые предложения!

const data = [
  {"t":"2020-05-27 03:42","v":"2.151"},
  {"t":"2020-05-27 08:48","v":"3.125"},
  {"t":"2020-05-27 11:54","v":"4.106"},
  {"t":"2020-05-27 18:00","v":"5.094"},
  {"t":"2020-05-27 21:06","v":"4.088"},
  {"t":"2020-05-27 23:12","v":"3.090"},
  {"t":"2020-05-28 00:18","v":"2.098"},
  {"t":"2020-05-28 03:24","v":"1.114"},
  {"t":"2020-05-28 08:30","v":"2.136"},
  {"t":"2020-05-28 12:36","v":"3.166"},
  {"t":"2020-05-28 17:42","v":"4.202"},
  {"t":"2020-05-28 22:48","v":"5.245"}, 
];

// STEP 1:
// Filter data to only return specific date "2020-05-27"
const today = data.filter( d => moment(d.t).format('YYYY-MM-DD') === '2020-05-27');
console.log('TODAY= ' + JSON.stringify(today));

// STEP 2:
// Divide today's data into half
const todayBeforeNoon = today.filter(d => moment(d.t).format('HH') <= '11');
const todayAfterNoon  = today.filter(d => moment(d.t).format('HH')  > '11');
console.log('TODAY BEFORE NOON= ' + JSON.stringify(todayBeforeNoon));
console.log('TODAY AFTER NOON= ' + JSON.stringify(todayAfterNoon));

// STEP 3:
// Get the max value per half day
const beforeNoonMax = todayBeforeNoon.reduce( (a, b) => { return (a.v > b.v) ? a : b}, 0);
const afterNoonMax  = todayAfterNoon.reduce(  (a, b) => { return (a.v > b.v) ? a : b}, 0);
console.log('MAX BEFORE NOON= ' + JSON.stringify(beforeNoonMax));
console.log('MAX AFTER NOON= ' + JSON.stringify(afterNoonMax));

// STEP 4:
// Get the min value per half day
const beforeNoonMin = todayBeforeNoon.reduce( (a, b) => { return (a.v < b.v) ? a : b}, 0);
const afterNoonMin  = todayAfterNoon.reduce(  (a, b) => { return (a.v < b.v) ? a : b}, 0);
console.log('MIN BEFORE NOON= ' + JSON.stringify(beforeNoonMin));
console.log('MIN AFTER NOON= ' + JSON.stringify(afterNoonMin));

// STEP 5:
// Combine the results into 1 array, and sort by time?
// HELP? SUGGESTIONS?
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.26.0/moment.min.js" integrity="sha256-5oApc/wMda1ntIEK4qoWJ4YItnV4fBHMwywunj8gPqc=" crossorigin="anonymous"></script>

Ответы [ 2 ]

1 голос
/ 28 мая 2020

Вот подход, который использует ha sh для организации данных. Ключ хеширования:

"yyyy-mm-dd-AM" or "yyyy-mm-dd-PM"

, который помещает объекты данных в подмассивы, которые легко обрабатывать.

const data = [
  { t: "2020-05-27 03:42", v: "2.151" },
  { t: "2020-05-27 08:48", v: "3.125" },
  { t: "2020-05-27 11:54", v: "4.106" },
  { t: "2020-05-27 18:00", v: "5.094" },
  { t: "2020-05-27 21:06", v: "4.088" },
  { t: "2020-05-27 23:12", v: "3.090" },
  { t: "2020-05-28 00:18", v: "2.098" },
  { t: "2020-05-28 03:24", v: "1.114" },
  { t: "2020-05-28 08:30", v: "2.136" },
  { t: "2020-05-28 12:36", v: "3.166" },
  { t: "2020-05-28 17:42", v: "4.202" },
  { t: "2020-05-28 22:48", v: "5.245" },
];

// create a hash object with properties
//    "yyyy-mm-dd-AM": [
//      {"t": "yyyy-mm-dd-AM hh:mm", "v": "1.234"},
//      ...
//    ],
//    "yyyy-mm-dd-PM": [],
//    ...
let hash = {};
data.forEach((tv) => {
  let [date, time] = tv.t.split(" ");
  let [hour, minute] = time.split(":");
  let meridian = hour >= 12 ? "-PM" : "-AM";
  let propName = date + meridian;
  hash[propName] = hash[propName] || [];
  hash[propName].push(tv);
});

// console.log("hash:", JSON.stringify(hash, null, 2));

let minmaxArray = [];

// iterate over each hash property
Object.values(hash).forEach((hashProp) => {

  // determine the min and max values in hashProp's array
  let vals = hashProp.map((tv) => tv.v);
  let vMin = Math.min(...vals);
  let vMax = Math.max(...vals);
  
  // push the min and max data elements onto array
  let tvMin = hashProp.filter((tv) => tv.v == vMin)[0];
  let tvMax = hashProp.filter((tv) => tv.v == vMax)[0];
  minmaxArray.push(tvMin);
  minmaxArray.push(tvMax);
});

// sort by date and time
minmaxArray.sort((a, b) => a.t.localeCompare(b.t));

const results = document.getElementById('results');
results.innerHTML = "minmaxArray: " +
  JSON.stringify(minmaxArray, null, 2);
Results:
0 голосов
/ 28 мая 2020

Одним из преимуществ форматирования, подобного ISO 8601, является то, что строковые и числовые методы могут применяться непосредственно для сортировки, группировки и сравнения, например

let data = [
  {"t":"2020-05-27 03:42","v":"2.151"},
  {"t":"2020-05-27 08:48","v":"3.125"},
  {"t":"2020-05-27 11:54","v":"4.106"},
  {"t":"2020-05-27 18:00","v":"5.094"},
  {"t":"2020-05-27 21:06","v":"4.088"},
  {"t":"2020-05-27 23:12","v":"3.090"},
  {"t":"2020-05-28 00:18","v":"2.098"},
  {"t":"2020-05-28 03:24","v":"1.114"},
  {"t":"2020-05-28 08:30","v":"2.136"},
  {"t":"2020-05-28 12:36","v":"3.166"},
  {"t":"2020-05-28 17:42","v":"4.202"},
  {"t":"2020-05-28 22:48","v":"5.245"}, 
];

             
let result = Object.values(
  // Sort, not really necessary but just to make sure
  data.sort((a, b) => a.t.localeCompare(b.t))
  // Group by date and am/pm
  .reduce((acc, el) => {
      let [d, t] = el.t.split(' ');
      let dayPeriod = parseInt(t) < 12? 'am' : 'pm';
      let key = d + '_' + dayPeriod;
      acc[key]? acc[key].push(el) : acc[key] = [el];
      return acc;
    }, {})
  )
  // Get just max and min for am and pm
  .reduce((acc, el) => {
      // Sort dayPeriod group on temperature
      el.sort((a, b) => a.v - b.v);
      // Min will be first, max will be last
      acc.push(el[0], el[el.length - 1]);
    return acc;
  }, []);
             
console.log(result)

Хотя я не фанат связывания множества вызовов функций. Я думаю, что лучше разделить его на отдельные операции, чтобы потом было легче поддерживать и изменять. Также проще реализовать проверку ошибок для отсутствующих или выходящих за границы значений.

...