【问题标题】:How to create an array of objects in order of timestamp based on the maximum and minimum values?如何根据最大值和最小值按时间戳顺序创建对象数组?
【发布时间】:2020-05-27 23:35:34
【问题描述】:

试图找到创建对象数组的最佳方法,其中我每天两次(中午 12:00 之前和中午 12:00 之后)只获得最大值和最小值。结果仍应按时间顺序返回。

我知道最好的方法是:

  1. 首先根据日期过滤数据(我正在使用moment.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?
&lt;script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.26.0/moment.min.js" integrity="sha256-5oApc/wMda1ntIEK4qoWJ4YItnV4fBHMwywunj8gPqc=" crossorigin="anonymous"&gt;&lt;/script&gt;

【问题讨论】:

    标签: javascript arrays date object timestamp


    【解决方案1】:

    这是一种使用哈希来组织数据的方法。哈希键是:

    "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:<br/>
    <pre id="results"></pre>

    【讨论】:

      【解决方案2】:

      类似于 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)

      我不喜欢链接大量函数调用。我认为最好将其拆分为离散的操作,以便以后更容易维护和修改。对缺失值或越界值进行错误检查也更容易。

      【讨论】:

        猜你喜欢
        • 2012-04-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-10-21
        • 2023-02-25
        • 2017-10-09
        • 2019-01-16
        • 1970-01-01
        相关资源
        最近更新 更多