Как создать массив week и записать в него дни недели в виде строк с одним циклом?

Нужна помощь в оптимизации кода. Есть следующая задача: создать массив week и записать в него дни недели в виде строк:

  1. Вывести на экран все дни недели
  2. Каждый из них с новой строчки
  3. Выходные дни - курсивом
  4. Текущий день - жирным шрифтом (использовать объект даты)

Написал такой код:

'use strict';
const week = ['Понедельник', 'Вторник', 'Среда', 'Четверг', 'Пятница', 'Суббота', 'Воскресенье'];
const day = document.querySelectorAll('.day-of-weeks');
const todayDay = new Date();

const days = () => {
    week.forEach((item, i) => {
        if (i === todayDay.getDay()) {
            day[i - 1].classList.add('today');
            day[i].classList.remove('today');
        }
    });
}

week.forEach((item, i, week) => {
    days();
    if (item == 'Суббота' || item == 'Воскресенье') {
        day[i].classList.add('italic');
        day[i].textContent = week[i];
    } else {
        day[i].textContent = week[i];
    }
});

Сделал "костыльно", пока не хватает опыта. Вижу, что не очень хорошо продумана логика. Получается, будет вызываться цикл каждую итерацию другого цикла.

Как сделать все в 1 цикл? И текущий день, кажется, не по индексу нужно получать, а как?


Ответы (4 шт):

Автор решения: OPTIMUS PRIME

"use strict";

insert_days();

/***/
function insert_days() {
  let lines = document.querySelectorAll(".day-of-week");
  
  let today_index = (6 + new Date().getDay()) % 7;
  lines[today_index].classList.add("bold");
  // он всего один, чтобы на каждой итерации не проверять if (i == today_index);
  
  /***/
  let days = ["Понедельник", "Вторник", "Среда", "Четверг", "Пятница", "Суббота", "Воскресенье"];
  days.forEach((day, i) => {
    if (i == 5 || i == 6) lines[i].classList.add("italic");
    lines[i].textContent = days[i];
  });
}
.italic {
  font-style: italic;
}
.bold {
  font-weight: bold;
}
<div class="day-of-week"></div>
<div class="day-of-week"></div>
<div class="day-of-week"></div>
<div class="day-of-week"></div>
<div class="day-of-week"></div>

<div class="day-of-week"></div>
<div class="day-of-week"></div>

(6 + new Date().getDay()) % 7 — это появилось из-за того, что:

              getDay дает:    А надо (для соответствия индексам массива):
Понедельник     1               0              // (6 + 1) % 7 → 0
Вторник         2               1              // (6 + 2) % 7 → 1
Среда           3               2              // (6 + 3) % 7 → 2
Четверг         4               3              // (6 + 4) % 7 → 3
Пятница         5               4              // (6 + 5) % 7 → 4
Суббота         6               5              // (6 + 6) % 7 → 5
Воскресенье     0               6              // (6 + 0) % 7 → 6

Но про "оптимизацию" реально надо думать только если у вас больше миллиона итераций и реально не устраивает скорость выполнения. Здесь же, речь идет всего лишь о более "правильном" оформлении.

Формально, если в массиве прям много элементов, подобную проверку if (i == 5 || i == 6) тоже можно вынести из цикла, и руками прописать lines[5].classList, lines[6].classList

«Магических числел» из серии % 7, == 6 тоже следует избегать, заменив их соответственно на lines.length или day == "Воскресенье", чтобы было понятно, о чем они. Но если задача достаточно простая, и в её контексте и так всё понятно, сойдет.


Другой вариант, "в лоб" )

let days = ["Понедельник", "Вторник", "Среда", "Четверг", "Пятница", "<i>Суббота</i>", "<i>Воскресенье</i>"];
    
let today_index = (6 + new Date().getDay()) % 7;
days[today_index] = `<b>${ days[today_index] }</b>`;
  
document.body.insertAdjacentHTML("beforeEnd", days.join("<br>"));

→ Ссылка
Автор решения: Denis640Kb

Добавил немного комментариев для понимания и убрал начальный HTML, который у Вас, видимо был.

'use strict';
const week = ['Понедельник', 'Вторник', 'Среда', 'Четверг', 'Пятница', 'Суббота', 'Воскресенье'];
const day = document.getElementById('fordays'); // Получаем div куда всё будем вставлять
const todayDay = new Date();

const days = () => {
    week.forEach((item, i) => {
        let newdiv = document.createElement('div'); // Для каждого элемента week создаём div
        if (i === +todayDay.getDay()-1) { // Если текущий день недели то от номера текущей даты отнимаем единицу, так как массив у нас начинается с нуля
            console.log(todayDay.getDay());
            newdiv.classList.add('today'); // Добавляем класс (делаем жирным)
            newdiv.textContent = week[i]; // Вставляем текст
        }
        if (item == 'Суббота' || item == 'Воскресенье') { // Если выходные то
            newdiv.classList.add('italic'); // Делаем дополнительно курсивом (Даже если уже жирным выделено)
            newdiv.textContent = week[i]; // Вставляем текст
        } else {
            newdiv.textContent = week[i]; // Если не текущий день и не выходные, то просто вставляем текст без стилей
        }
        day.appendChild(newdiv); // Добавляем новый див в div @day

    });
};
days(); // Вызываем функцию;
    .today{
        font-weight: 700;
    }
    .italic{
        font-style: italic;
    }
<div id="fordays"></div>

→ Ссылка
Автор решения: Евгений Колмак
const week = ['Понедельник', 'Вторник', 'Среда', 'Четверг', 'Пятница', 'Суббота', 'Воскресенье'];
const day = document.querySelector('#day');
const date = new Date();
const todayDay = date.getDay() - 1;

for (let i = 0; i < 7; i++) {
  if (i < 5 && i != todayDay) {
    day.innerHTML += `${week[i]}<br>`;
  }
  if (i > 4) {
    day.innerHTML += `<b>${week[i]}</b><br>`;
  }

  if (i === todayDay) {
    day.innerHTML += `<i>${week[i]}</i><br>`;
  }

}
→ Ссылка
Автор решения: Danil Maiorov

Я решил таким образом.

//исходный массив
const week = ['Понедельник', 'Вторник', 'Среда', 'Четверг', 'Пятница', 'Суббота', 'Воскресенье']; 
//получаю сегодняшнюю дату, сразу за вычетом -1, 
//чтобы осуществить проверку на воскресенье 
//(поскольку в методе getDay() воскресенье 0)
let today = new Date().getDate() - 1; 
if (today === -1) { // и если переменная today = -1
  today = 6; // то присваиваем ей значение 6
}
week.forEach((item, index) => { // перебор массива по item и index
  const weekDay = document.createElement('div'); // создаю div для верстки
  weekDay.innerHTML = `<p>${item}</p>`; // создаю верстку и интерполяцией вывожу текст элемента массива
  if (index > 4) { // если индекс больше 4, то это выходные 
    weekDay.style.fontStyle = 'italic'; // и они выводятся курсивом
  }
  if (index === today) { // если индекс совпадает с значением переменной today
    weekDay.style.fontWeight = 'bold'; // то выводим жирным
  }
  document.body.append(weekDay); // ну и собственно выводим верстку на экран
});

→ Ссылка