使用reduce to group date来生成date_from和date_to

时间:2017-06-13 06:21:59

标签: javascript ecmascript-6 momentjs

如何改变这种结构

[
    {date_from:'15-6-2017'},
    {date_from:'16-6-2017'},
    {date_from:'17-6-2017'},
    {date_from:'29-6-2017'}
    {date_from:'30-6-2017'}
]

到此?

[
    {id:1,date_from:'15-6-2017',date_to:'17-6-2017'},
    {id:2,date_from:'29-6-2017',date_to:'30-6-2017'}
]
幸运的是,订单已经是正确的,我脑子里流行的是减少,我仍然卡住了。我正在使用片刻。

4 个答案:

答案 0 :(得分:1)

这是您的代码的解决方案,您可以根据需要添加格式。



let string = [{
    date_from: '15-6-2017'
  },
  {
    date_from: '16-6-2017'
  },
  {
    date_from: '17-6-2017'
  },
  {
    date_from: '29-6-2017'
  },
  {
    date_from: '30-6-2017'
  }
];

//split them and pull out any white spaces from beginning and end
let dates = string.map(s => {
  s = s.date_from.trim();
  let nums = s.split('-');
  let d = new Date(nums[2], nums[1], nums[0]);
  return {
    date: d,
    string: s
  };
});
let currentStart = dates[0];
let result = [];
for (let i = 1; i < dates.length; i++) {
  let {
    date,
    string
  } = dates[i];
  //If last date, add range
  if (i == dates.length - 1) {
    console.log("hello");
    result.push({
      start: currentStart.string,
      end: string
    });
  } else {
    let prevDate = dates[i - 1] || currentStart; //in case prevDate is undefined
    let nextDate = dates[i + 1];
    let diff = nextDate.date.getTime() - date.getTime();
    if (diff > (24 * 60 * 60 * 1000)) {
      result.push({
        start: currentStart.string,
        end: string
      });
      currentStart = nextDate;
    }
  }
}

console.log(result, 'result');
&#13;
&#13;
&#13;

这是代码的代码,因此您可以随时编辑它。 demo

答案 1 :(得分:1)

你是对的,可以通过reduce来轻松完成:

&#13;
&#13;
var dates = [
    {date_from:'15-6-2017'},
    {date_from:'16-6-2017'},
    {date_from:'17-6-2017'},
    {date_from:'29-6-2017'},
    {date_from:'30-6-2017'}
];

var toT = (d)=>Date.parse(d.split('-').reverse().join('/'))

var out = dates.reduce((newArr,d,i)=>{
  if (i==1) newArr = [{id:1,date_from:newArr.date_from,date_to:newArr.date_from}];
  var prevD = newArr[newArr.length-1].date_to;
  if (toT(prevD) + (24*60*60*1000) == toT(d.date_from)) newArr[newArr.length-1].date_to = d.date_from;
  else newArr.push({id:newArr.length+1,date_from:d.date_from,date_to:d.date_from})
  return newArr;
})

console.log(out)
&#13;
&#13;
&#13;

答案 2 :(得分:1)

您可以检查与最后一天的差异,如果差异不等于一,则插入一个新对象。

基本上它试图获取结果数组的最后一个日期,如果未设置,则使用空对象。然后,它获取date_to属性的值,并将值转换为moment对象,以便稍后与date_from进行比较。

在检查所需差异一天后,date_from属性会获得更新。如果差异不是1,则将新对象添加到结果集中。

var data = [{ date_from: '15-6-2017' }, { date_from: '16-6-2017' }, { date_from: '17-6-2017' }, { date_from: '29-6-2017' }, { date_from: '30-6-2017' }],
    id = 1,
    grouped = data.reduce(function (r, o) {
        var last = moment((r[r.length - 1] || {}).date_to, 'D-M-Y');

        if (moment(o.date_from, 'D-M-Y').diff(last, 'd') === 1) {
            r[r.length - 1].date_to = o.date_from;
        } else {
            r.push({ id: id++, date_from: o.date_from, date_to: o.date_from });
        }
        return r;
    }, []);

console.log(grouped);
.as-console-wrapper { max-height: 100% !important; top: 0; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.15.2/moment.min.js"></script>

答案 3 :(得分:0)

似乎是这样的:

var setToDate = function(dateStr, days) {
  var d = dateStr.split('-')
  var date = new Date(d[2], d[1], d[0])
  date.setDate(date.getDate() + days);
  return date.getDate() + '-' + date.getMonth() + '-' + date.getFullYear();
}

var arr = [
    {date_from:'15-6-2017'},
    {date_from:'16-6-2017'},
    {date_from:'17-6-2017'},
    {date_from:'29-6-2017'},
    {date_from:'30-6-2017'}
]

for(var i=0; i<arr.length; i++) {
    arr[i].id = i+1;
    arr[i].date_to = setToDate(arr[i].date_from, 1);
}

console.dir(arr)