Использование Lodash pad для форматирования самого первого числа цикла for на основе условия

#javascript #arrays #lodash

#javascript #массивы #Lodash

Вопрос:

Я создал консоль.ведение журнала календаря через node js с использованием moment framework. Моя проблема заключается в применении pad специально в первый день месяца, чтобы он соответствовал своему дню. Например. если их первый день — четверг, я бы хотел, чтобы первый день (1) начинался в четверг, а затем прерывал строку после субботы. Наконец, это прервется и цикл будет продолжаться до разрыва строки через каждые 7 дней.

На данный момент мой календарь начинается с первого дня и корректно прерывается, но первый день (1) всегда приходится на воскресенье из-за моего непонимания того, как заполнять первое число. Еще одна вещь, на которую следует обратить внимание, это то, что в моем календаре сейчас только 7, но это потому, что я знаю, как делать правильные отступы / разрывы строк после первой строки.

 let days = moment.weekdays().join(' ');
// Array of months
let theMonths = moment.monthsShort();

// Creation of each month
for (i = 0; i < theMonths.length; i  ) {
  // Assigns each month to a variable to call moment functions
  var eachMonth = moment().month(theMonths[i]);
  // Creates calendar for each month
  console.log("-------"   theMonths[i]   "------");
  console.log(days);
  console.log(monthDays(eachMonth))
}

// this function handles creating all days of each month
function monthDays(month) {

  let display = '';
  for (x = 1; x <= month.daysInMonth(); x  ) {
    if (x <= 7) {
      var holder = moment.weekdays().length;
      // subtracting the length of the week from the starting day of each month
      var firstLine = holder - month.weekday();
      // will break line based on first day
      if (x == firstLine) {
        display  = "   "   x   "n";
      } else {
        // padding for each number after(if neccesary) line break
        display  = _.pad(x   " ", 8);

      }
    }
  }
  console.log(display)
}     
  

Ожидаемые результаты:

     Oct has: 31 days the first day is: 2
    -------Oct------
    Sunday Monday Tuesday Wednesday Thursday Friday Saturday
                      1       2       3       4       5
       6       7      etc.
  

Фактические результаты:

     Oct has: 31 days the first day is: 2
    -------Oct------
    Sunday Monday Tuesday Wednesday Thursday Friday Saturday
       1       2       3       4       5
       6       7       etc.
  

Комментарии:

1. что не так с вашим отступом и закрывающими скобками? Этот код не будет выполняться.

2. да, srry, в функции есть несколько дополнительных скобок, потому что я не пытался скопировать код, который не имеет отношения к проблеме.

3. @AuronKelmud используете ли вы JS в браузере или Node.js.

Ответ №1:

Вы можете использовать заполнение другим способом, вот пример и документация: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/padStart

 String.prototype.padStart();
String.prototype.padEnd();
  

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

Если мы знаем, что самая длинная строка содержит, например, 7 букв, мы могли бы предположить, что заполнение в 10 будет поддерживать порядок.

 // 'abc'.padStart(10);         // "       abc"
// 'abc'.padStart(10, "foo");  // "foofoofabc"

function output() {
    console.log('Expected Results:');
    console.log('Day has:', '# days from the first day is: #');
    console.log(
        ' Day'.padStart(0),
        'Day'.padStart(7),
        'Day'.padStart(7),
        'Day'.padStart(7),
        'n',
        '#'.padStart(0),
        '#'.padStart(7),
        '#'.padStart(7),
        '#'.padStart(7),
        'n',
        'Day'.padStart(0),
        'Day'.padStart(7),
        'Day'.padStart(7),
        'Day'.padStart(7),
        'n',
        '#'.padStart(0),
        '#'.padStart(7),
        '#'.padStart(7),
        '#'.padStart(7),
    );
}

output();  

Тогда, если вы используете Node.JS вы могли бы использовать padStart() и padEnd() в сочетании с шириной терминала.

 console.log('Size'   process.stdout.columns   'x'   process.stdout.rows);
  

Ответ №2:

Некоторые проблемы:

  • Вы предполагаете, что month.weekday(); получает день недели первого числа месяца, но когда вы просто создаете момент для месяца, текущий день и время сохраняются в этот момент, поэтому вам нужно применить .startOf("month")
  • Вы console.log возвращаете значение вызова функции, но функция ничего не возвращает; вместо этого она выводит что-то сама.
  • В настоящее время вы выходите из цикла на день номер 7. Конечно, вы хотите также выводить другие дни месяца 😉
  • Вы используете глобальные переменные для переменных цикла. Обязательно объявите их с локальной областью видимости

Вот как можно было бы адаптировать ваш код. Комментарии указывают, где были внесены изменения:

 const days = moment.weekdays().join(' ');
const theMonths = moment.monthsShort();
/// Don't use a global variable -- declare i:
for (let i = 0; i < theMonths.length; i  ) {
    const eachMonth = moment().month(theMonths[i]).startOf("month"); /// <--- get first day
    console.log("-------"   theMonths[i]   "------");
    console.log(days);
    console.log(monthDays(eachMonth));
}

function monthDays(month) {
    const shift = month.weekday(); // Get shift of "1"
    const holder = moment.weekdays().length;
    let display = ' '.repeat(8 * shift); // Create indentation for "1"
    for (let x = 1; x <= month.daysInMonth(); x  ) {
        const firstLine = x > 1 amp;amp; (x-1 shift) % holder == 0; // <-- the magic!
        if (firstLine) display  = "n";
        display  = _.pad(x   " ", 8);
    }
    return display; // <--- return
}  
 <script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.15.0/moment.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.16.4/lodash.min.js"></script>  

Комментарии:

1. большое спасибо за этот ответ, многое проясняет для меня