填写顺序数据的缺失日期

时间:2018-01-29 16:04:35

标签: javascript lodash

我的输入数据格式为:



{
"BeginDate": "2017-01-05",
"EndDate": "2017-01-31",
"Points": [
  {
    "Date": "2017-01-05",
    "Value": 64
  }, 
  {
    "Date": "2017-01-08",
    "Value": 251
  }, 
  {
    "Date": "2017-01-15",
    "Value": 144
  }, 
  {
    "Date": "2017-01-29",
    "Value": 216
  }]
}




除了BeginDate,其他日期是一周的开始。 对于我来说,为缺失的日期自动填0,这可能是一个好方法,例如" 2017-01-22"?

我的预期输出是:



{
"BeginDate": "2017-01-05",
"EndDate": "2017-01-31",
"Points": [
  {
    "Date": "2017-01-05",
    "Value": 64
  }, 
  {
    "Date": "2017-01-08",
    "Value": 251
  }, 
  {
    "Date": "2017-01-15",
    "Value": 144
  },
  {
    "Date": "2017-01-22",
    "Value": 0
  },
  {
    "Date": "2017-01-29",
    "Value": 216
  }]
}




2 个答案:

答案 0 :(得分:1)

从开始日期创建nextWeek。使用while循环检查每一周是否存在,然后在nextWeek超过结束日期<7>之前增加7天

&#13;
&#13;
const end = new Date(data.EndDate),
  start = new Date(data.BeginDate),
  nextWeek = new Date(start);
// adjust to Sunday
nextWeek.setDate(start.getDate() + (7 - start.getDay()) % 7);

while (+nextWeek <= +end) {
  // create formated date string YYYY-MM-DD
  const dateStr = [nextWeek.getFullYear(), padNum(nextWeek.getMonth() + 1), padNum(nextWeek.getDate())].join('-'),
    // see if that Date exists
    weekExists = data.Points.find(o=> o.Date === dateStr);
  if (!weekExists) {
    // push new point if not
    data.Points.push({ Date: dateStr,  Value: 0  })
  }
  // increment 7 days
  nextWeek.setDate(nextWeek.getDate() + 7)
}

// sort Points if needed
data.Points.sort((a,b) => new Date(a.Date)- new Date(b.Date));

console.log(JSON.stringify(data.Points))

// helper to add leading zeros
function padNum(num) {
  return ('0' + num).slice(-2)
}
&#13;
<script>
  var data = {
    "BeginDate": "2017-01-05",
    "EndDate": "2017-01-31",
    "Points": [{
      "Date": "2017-01-05",
      "Value": 64
    }, {
      "Date": "2017-01-08",
      "Value": 251
    }, {
      "Date": "2017-01-15",
      "Value": 144
    }, {
      "Date": "2017-01-29",
      "Value": 216
    }]
  }

</script>
&#13;
&#13;
&#13;

答案 1 :(得分:0)

以下几乎是这样做的。如果您需要任何帮助来解释代码的作用,请告诉我。

var data = {
  "BeginDate": "2018-01-05",
  "EndDate": "2018-01-31",
  "Points": [
    {
      "Date": "2018-01-05",
      "Value": 64
    }, 
    {
      "Date": "2018-01-08",
      "Value": 251
    }, 
    {
      "Date": "2018-01-15",
      "Value": 144
    }, 
    {
      "Date": "2018-01-29",
      "Value": 216
    }]
  };
var mondays = (dates=[]) => start => end => {
  if(start>=end){
    return dates;
  }
  const newStart = new Date(start.getTime());
  if(newStart.getDay()!==1){
    return mondays(dates)(
      //optimization from charlietfl except getting mondays
      new Date(newStart.setDate(newStart.getDate() + (8 - newStart.getDay()) % 7))
    )(end);
  }
  return mondays
    (
      (start.getDay()===1)
        ? dates.concat([start])
        : dates
    )
    (
      new Date(newStart.setDate(newStart.getDate()+7))
    )
    (end);
}
var twoDigits = num =>//or you could try leftPad
  ("00"+num.toString()).slice(-2);
//dates are indeed iso 8601
var dataWithAllMondays = mondays()(new Date(data.BeginDate))(new Date(data.EndDate))
.map(
  date=>
    `${date.getFullYear()}-${twoDigits(date.getMonth()+1)}-${twoDigits(date.getDate())}`
)
.reduce(
  (data,date)=>{
    if(data.Points.filter(d=>d.Date===date).length===0){
      return {
        ...data,
        Points:data.Points.concat([{
          Date:date,Value:0
        }])
      };
    }
    return data;
  },
  data
);
dataWithAllMondays.Points=dataWithAllMondays.Points.sort(
  (a,b)=>
    (a.Date>b.Date)//there is no a === b
      ? 1
      : -1
)
console.log(dataWithAllMondays.Points);