[{date:'2017-8-1'},{date:'2017-8-2'},{date:'2017-8-3'},{date:'2017-8-5'},{date:'2017-8-6'},{date:'2017-8-7'},{date:'2017-8-8'},{date:'2017-8-9'}]

У меня есть данные выше, я пытаюсь сгруппировать последние 2 элемента и присвоить им свойство «выходные», а остальное - «будний день», мой ожидаемый результат такой:

{
    weekdays: [{date:'2017-8-1'},{date:'2017-8-2'},{date:'2017-8-3'},{date:'2017-8-5'},{date:'2017-8-6'},{date:'2017-8-7'}],
    weekends: [{date:'2017-8-8'},{date:'2017-8-9'}]
}

У меня была неудачная попытка

data.map((obj, i) => {

    if(data.length - (i + 1) >= 2) {
        return {
            weekdays: {
                date: moment(obj.date)
            }
        }
    }

    return {
        weekends: {
            date: moment(obj.date)
        }
    }
})
1
Cecilia Chan 28 Авг 2017 в 13:42

6 ответов

Лучший ответ

Если вы не уверены, в каком порядке будут дни:

days = [{date:'2017-8-1'},{date:'2017-8-2'},{date:'2017-8-3'},{date:'2017-8-5'},{date:'2017-8-6'},{date:'2017-8-7'},{date:'2017-8-8'},{date:'2017-8-9'}]

const isWeekend = day => (
  [6, 0].includes(new Date(day.date).getDay())
);

const separate = (days) => {
  const weekends = [];
  const weekdays = [];
  days.forEach((day) => {
    isWeekend(day) ? weekends.push(day) : weekdays.push(day);
  });
  return { weekends, weekdays };
};

console.log(separate(days));
1
Zevgon 31 Авг 2017 в 16:38

Если вы точно знаете, что выходные дни всегда являются последними двумя элементами во входном массиве, вы можете сделать это с помощью простого slice.

var inputArray = [{date:'2017-8-1'},{date:'2017-8-2'},{date:'2017-8-3'},{date:'2017-8-5'},{date:'2017-8-6'},{date:'2017-8-7'},{date:'2017-8-8'},{date:'2017-8-9'}],
outputArray = {
  weekdays: inputArray.slice(0,5),
  weekends: inputArray.slice(6)
};

console.log(outputArray);
1
Thijs 28 Авг 2017 в 10:47

Вы можете конвертировать строки в даты, а затем использовать метод .getDay(), чтобы узнать, какой сегодня день. Затем просто поместите его в соответствующие массивы следующим образом:

var array = [{date:'2017-8-1'},{date:'2017-8-2'},{date:'2017-8-3'},{date:'2017-8-5'},{date:'2017-8-6'},{date:'2017-8-7'},{date:'2017-8-8'},{date:'2017-8-9'}];
var obj = {
    weekdays: [],
    weekends: []
};

array.forEach((el, key) => {
    if(new Date(el.date).getDay() === 0 || new Date(el.date).getDay() === 6) obj.weekends.push(el); else obj.weekdays.push(el);
});

console.log(obj);
0
curveball 28 Авг 2017 в 11:18

Чтобы добавить к другим ответам и объяснить, почему ваша попытка не удалась: это случай Array.reduce, а не Array.map. Последний предназначен для возврата одного элемента для каждого элемента во входном массиве, тогда как reduce может использоваться для «сворачивания» массива в одно значение, объект или что-то еще (что мы и хотим).

Элегантное решение может выглядеть так:

const outObj = inArr.reduce(function(obj, current, i) {
    if(i >= 5) { // or other check for weekend, depending on your data
      return Object.assign(obj, { weekends : obj.weekends.push(current) })
    } else {
      return Object.assign(obj, { weekdays : obj.weekdays.push(current) })
    }
  }, { weekdays : [], weekends : [] })

В приведенном выше фрагменте кода функция, которую мы передаем, запускается на каждом элементе ввода, как в map. Принципиальное отличие состоит в том, что он может получить доступ к выходным данным, которые были получены при последнем запуске функции, которая передается в качестве первого параметра (в этом примере называемого obj). Кстати, вторым параметром, который передается в reduce, является начальное состояние obj (объект с двумя пустыми списками).

Этот подход позволяет постепенно заполнять один объект, а не создавать n разные объекты, например вашу map версию.

0
zinfandel 28 Авг 2017 в 11:05

Поскольку вы уже используете momenjs, вы можете преобразовать свой массив в массив moment объектов, используя map(), а затем просто filter с использованием isoWeekday() метод:

var array = [{date:'2017-8-1'},{date:'2017-8-2'},{date:'2017-8-3'},{date:'2017-8-5'},{date:'2017-8-6'},{date:'2017-8-7'},{date:'2017-8-8'},{date:'2017-8-9'}];

var momentArray = array.map(function(d){ return moment(d.date, "YYYY-M-D"); });

var obj = {
    weekdays: momentArray.filter(function(d){ return d.isoWeekday() < 6 }),
    weekends: momentArray.filter(function(d){ return d.isoWeekday() > 5 })
};

console.log(obj);
<script src="//cdnjs.cloudflare.com/ajax/libs/moment.js/2.18.1/moment.min.js"></script>
0
Stanislav Kvitash 28 Авг 2017 в 11:13

Вы не возвращаете переменную и не возвращаете массив. Попробуйте использовать foreach и добавьте свои свойства в переменную.

Вместо вашего текущего решения попробуйте это;

newOb = {};
Array.forEach((o,i)=>{
If(i>(array.length-2)-1){
newOb.weekend == undefined? newOb.weekend=[o]:newOb.weekend.push(o);}
else{
newOb.weekday == undefined? newOb.weekday = [o]: newOb.weekday.push(o);}});
0
Onome 28 Авг 2017 в 11:59