используйте сокращение до групповой даты, чтобы сделать date_from и date_to

1

Как преобразовать такую структуру

[
    {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'}
]

к счастью, заказ уже правильный, что поп в моем сознании уменьшается, я все еще застрял. Я использую момент.

Теги:
ecmascript-6
momentjs

4 ответа

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');

это код кода, поэтому вы можете редактировать его в любое время. демонстрация

  • 0
    отличная работа, но я не могу использовать это, мне нужно использовать момент, чтобы избежать длинного кода.
1

Вы можете просто проверить разницу с последнего дня и вставить новый объект, если разница не равна единице.

В основном он пытается получить последнюю дату из массива результатов, и если он не установлен, он использует пустой объект. Затем он берет значение свойства date_to и преобразует значение в moment объекта для последующего сравнения с date_from.

После проверки с необходимой разницей на один день свойство date_from получает обновление. Если разница не подходит для одного, в результирующий набор добавляется новый объект.

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>
  • 0
    элегантное решение, не задумывалось об использовании r.length - 1. Отлично, если вы можете шаг за шагом объяснить, как это работает.
1

Вы правы, это можно сделать довольно легко с уменьшением:

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)
  • 1
    Что делает var toT = (d)=>Date.parse(d.split('-').reverse().join('/')) ?
  • 0
    Получив метку времени из вашего формата даты, превратили ее в отдельную функцию для сокращения кода.
Показать ещё 2 комментария
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)
  • 0
    что? ты вообще понимаешь вопрос?
  • 1
    @AlanJenshen проверьте сейчас

Ещё вопросы

Сообщество Overcoder
Наверх
Меню