Задать вопрос
Ответы пользователя по тегу JavaScript
  • В чем моя ошибка stepik?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    произведение элементов массива
    let p = 1;
    // в цикле:
    p *= arr[i];


    кратных 3
    n % 3 === 0

    оканчивающихся на 5
    n % 10 === 5

    если таких элементов нет
    в общем случае делается введением флага:
    let hasElements = false;
    
    if (/* ... */) {
      hasElements = true;
    }
    Но конкретно в этом случае, так как 1 гарантированно не попадает под условия, а все остальные числа изменят произведение, можно проще p !== 1

    Вам осталось дело за малым, объединить эти кусочки знаний в единый алгоритм
    Ответ написан
    Комментировать
  • Что сделать с большими аудиофайлами, чтобы их было удобно слушать на веб-странице?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    Я бы пошел путем разбиения файла на куски, это кстати можно автоматизировать через ffmpeg.
    Так же лучше сохранять информацию о всех кусках и их продолжительности (например в json).

    Для непрерывного воспроизведения стоит создавать новый audio и вставлять его на страницу за некоторое время до окончания воспроизведения текущего куска. Отслеживать время можно через событие timeupdate.
    По завершению текущего куска (событие ended) запускать следующий, а элемент audio текущего удалять из страницы.

    Если нужен ползунок, эмулирующий полный файл, то можно сделать кастомный используя информацию из json. Хотя для личного пользования я лично не стал бы заморачиваться и просто вывел бы кнопки для переключения на нужный кусок, все так же на основе информации из json.
    Ответ написан
  • Почему не работает цикл?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    Во-первых, у Вас ошибка синтаксиса
    https://developer.mozilla.org/ru/docs/Web/JavaScri...

    Во-вторых, а что Вы пытаетесь добиться, запуская setInterval в цикле, а в setInterval еще один setInterval?
    Ответ написан
  • Не понимаю последовательность выполнения цикла?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    Для начала почитайте вот это:
    https://developer.mozilla.org/ru/docs/Web/JavaScri...

    Если после прочтения так сходу не понятно, то возьмите листочек с ручкой и распишите свой алгоритм по шагам.
    Ответ написан
    Комментировать
  • Почему JS меняет дату?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    Дата не меняется, просто Вы оперируете датой в текущем часовом поясе (Московское время), а в консоль логируется в формате UTCString, а в UTC всегда используется время по Лондону.

    Ну и у строки нет метода setHours, нужно сначала создавать объект Date и уже на нем вызывать этот метод. Хотя для даты сделаной из такой строки этот вызов бессмысленный, так как устанавливаемые параметры и так будут 0
    Ответ написан
    2 комментария
  • Как упростить проверку числа на палиндром и увеличить скорость выполнения кода?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    Задача проверки последовательности на палиндром решается за O(n/2). Но для этого нужно иметь последовательный доступ к обоим концам последовательности за O(1).
    Если такой возможности нет и имеется доступ только к одному из концов последовательности, то придется обойти всю последовательность, а это уже O(n). Один из таких, достаточно оптимальных алгоритмов для цифр целого числа уже представил WbICHA.

    Чтоб решить эту задачу за O(n/2) нужно понять, как получить крайние цифры числа за O(1).
    Крайнюю справа цифру можно получить простым остатком от деления на основание системы счисления, то есть, в случае десятичной системы счисления, на 10.
    Для получения крайней справа цифры нужно знать ее порядок (считая справа начиная с 0). Это можно сделать взяв целую часть от логарифма по основанию системы счисления (10). На JS такая операция будет выглядеть так:
    Math.trunc(Math.log10(num))
    Целая часть от деления числа на 10 в степени порядка правой цифры даст саму эту цифру. На JS это выражается так:
    Math.trunc(num / 10 ** Math.trunc(Math.log10(num)))

    Так же алгоритм требует равномерного перемещения по последовательности от краев к центру.
    Для правой цифры опять все просто, можно брать целую часть от деления числа на основание (10).
    Для левой нужно умножить ее на основание в степени порядка и вычесть результат из самого числа, то есть:
    num - leftDigit * 10 ** Math.trunc(Math.log10(num))


    Осталось учесть пограничные условия:
    1. Если крайний левый и крайний правый элемент не равны, то последовательность не является палиндромом
    2. Последовательность из одного элемента (число из одной цифры) всегда палиндром.
    3. При равенстве крайних элементов последовательность будет палиндромом если палиндромом так же является подпоследовательность без этих элементов.

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

    По итогу получим такую функцию:
    const isPalindrome = num => {
        let n = num;
        while (n >= 10) {
            const order = 10 ** Math.trunc(Math.log10(n));
            const leftDigit = Math.trunc(n / order);
            const rightDigit = n % 10;
            if (leftDigit !== rightDigit) return false;
            n -= leftDigit * order;
            n /= 10;
            n = Math.trunc(n);
        }
        return true;
    };


    P.S. варианты с приведением числа к строке, а тем более с последующим разбиением на массив чисел и разворотом его, просто отвратительны.
    Приведение числа к строке - это O(n) если не больше, так как в JS тип number - это по сути float64 и алгоритм приведения учитывает, что число может быть с дробной частью.
    Разбиение строки на массив символов (split) - O(n) и требует доп памяти под этот массив.
    Реверс массива - O(n/2)
    Склейка (join) - опять O(n)
    Сравнение строк - еще раз O(n)
    И хотя суммарная сложность останется O(n), количество проходов по цифрам числа будет в 5 раз больше, хотя даже на строках можно уложится в 1.5 обхода:
    const isPalindrome = num => {
        const s = String(num);
        for (let i = 0; i < s.length / 2; i++) {
            if (s[i] !== s[s.length - i - 1]) return false;
        }
        return true;
    };
    Ответ написан
    4 комментария
  • Как переключить подсветку на следующий элемент списка при нажатии стрелок вверх-вниз?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    Ну для начала, вот сюда:
    list.addEventListener('keydown', function(parentLi) {
    параметром придет KeyboardEvent, в котором есть данные о нажатых клавишах.

    По идее в цикле перебираются li с классом parent, и у того, который должен быть подсвечен добавляется к классу пометка active
    Хранить состояние во view слое очень плохая идея. Запоминайте индекс выделенного элемента в переменной и по событию проверяйте возможность переключения подсветки и меняйте классы.

    Ну и так, замечание:
    for(var i = 0; i < parentLi.length; i++) {
        light(parentLi[i].firstChild)
    }
    
    function light(parentLi) {
        parentLi.addEventListener('mouseover', function() {
            this.style.color = 'pink';
            this.style.backgroundColor = 'grey';
        })
        parentLi.addEventListener('mouseout', function() {
            this.style.color = 'black';
            this.style.backgroundColor = 'white';
        })
    }
    вот тут в цикле создается целая пачка однотипных функций, каждая из которых будет жрать память пользователя. Притом эта задача вообще легко решается на чистом CSS через hover.
    Ответ написан
  • Как правильно копировать интерфейс и переносить функции, события в TypeScript?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    1. У Вас переменная design нигде не объявлена, откуда она должна взяться-то? Аналогично будет с другими переменными: designActive, designNoActive, development, developmentActive, developmentNoActive, promotion, promotionActive, promotionNoActive
    2. Что мешает просто сделать import?
    Ответ написан
    1 комментарий
  • Регулярное выражение url?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    Не нужны здесь регулярки.
    https://developer.mozilla.org/ru/docs/Web/API/URLS...
    Ответ написан
    Комментировать
  • Как типизировать функцию, которая возвращает данные по ключам объекта?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    const DEFAULT_KEY = 'defaultKey';
    type DEFAULT_KEY = typeof DEFAULT_KEY;
    
    type BaseObject = Record<PropertyKey, Record<PropertyKey, unknown>>;
    
    type PropertyOfObject<T extends BaseObject> = {
        <K extends keyof T>(key: K): DEFAULT_KEY extends keyof T[K] ? T[K][DEFAULT_KEY] : null;
        <K0 extends keyof T, K1 extends keyof T[K0]>(key0: K0, key1: K1): T[K0][K1];
    };
    
    function getPropertyOfObject<T extends BaseObject>(obj: T): PropertyOfObject<T> {
      type K0 = keyof T;
      type K1 = DEFAULT_KEY | keyof T[K0];
      return ((keyOne: K0, keyTwo: K1 = DEFAULT_KEY) =>
        obj[keyOne]?.[keyTwo] ?? null
      ) as PropertyOfObject<T>;
    }

    https://www.typescriptlang.org/play?#code/MYewdgzg...
    Ответ написан
    6 комментариев
  • Что хранит в себе данная функция?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    Комментировать
  • Как написать скрипт в package.json?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    Не надо ничего мудрить, просто поставьте ; в конце команды
    Ответ написан
    4 комментария
  • JSON.Stringify со ссылками?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    Сам формат JSON не имеет поддержки рекурсивных и перекрёстных ссылок, однако можно сделать свой формат поверх JSON с такой поддержкой.
    JSON.stringify поддерживает параметр replacer, а JSON.parse - параметр reviver, которые позволяют обрабатывать каждое значение при сериализации/десериализации
    Ответ написан
  • Насколько плоха идея сохранять все параметры запроса к странице в cookie?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    Дать бэкендеру почитать что такое куки и для чего они нужны, например вот: https://developer.mozilla.org/ru/docs/Web/HTTP/Cookies
    Объяснить, что забивать гвозди микроскопом не лучшая идея, даже если он так привык.
    Если напрямую действовать не получается, то можно через техлида или тимлида.

    Есть ли аргументы против этого?
    хотя бы то что куки - это долговременное хранилище, а никак не средство общения клиента с сервером

    Бэкенд-программист очень любит extract($_POST);
    на сколько помню php, get параметры передаются в $_GET и никак не аффектят $_POST
    Ответ написан
  • Переключение классов по времени?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    if (hours === 10 || (hours === 11 && minutes < 30)) {
      // 1
    } else if ((hours === 11 && minutes >= 30) || hours === 12) {
      // 2
    }


    Но проще вычислить даты для контрольных точек и сравнивать текущее время с ними:
    function createDate(hours, minutes) {
      const d = new Date();
      d.setHours(hours);
      d.setMinutes(minutes);
      return d;
    }
    
    const time1 = createDate(10, 0).getTime();
    const time2 = createDate(11, 30).getTime();
    const time3 = createDate(13, 0).getTime();
    const now = Date.now();
    if (now >= time1 && now < time2) {
      // 1
    } else if (now >= time2 && now < time3) {
      // 2
    }


    Ну и так же стоит учитывать, что считать это все будет в часовом поясе пользователя, если же нужны вычисления независимые от часового пояса, то стоит использовать методы setUTCHours и setUTCMinutes со смещениями нужного часового пользователя относительно UTC (Лондона) ну или getUTCHours/getUTCMinutes для первого варианта.
    Ответ написан
    Комментировать
  • Как правильно получить остаток времени?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    Date.now() - new Date('2021-11-02T18:44:16').getTime()
    результат будет в миллисекундах, часы/минуты из них можно получить обычным делением
    Ответ написан
    3 комментария
  • Почему функция не видит переменную?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    А кто текст ошибки будет читать?
    Uncaught TypeError: [1,2,3] is not a function

    Лучше всегда использовать точку с запятой, чтоб таких ошибок не было.
    Конкретно тут возникает ситуация, что круглые скобки вокруг функции являются продолжением выражения с массивом, то есть работает это по сути так:
    let map = [1, 2, 3](async () => {
    	console.log(map)
    })()
    Ответ написан
    Комментировать
  • Как принимать и посылать пост запросы (express node.js)?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    Для отправлять запросы из ноды есть вот:
    https://nodejs.org/dist/latest-v17.x/docs/api/http...
    https://www.npmjs.com/package/node-fetch

    Для принимать:
    expressjs.com/en/4x/api.html#app.post.method
    Ответ написан
    Комментировать
  • Блекджек на js?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    1. Массивы индексируются с 0 а не с 1
    randomInteger(1,6)


    2. Проверка на проигрыш логически должна быть раньше чем запрос новой карты

    3. Рекурсия имеет ограниченную вложенность, хотя если исправить ошибку №2, то Вы в нее не упретесь, но тем не менее не зачем использовать рекурсию там, где легко можно обойтись циклом:
    const cards = [6, 7, 8, 9, 10, 11];
    
    function randomArrayElement(array) {
      return array[Math.floor(Math.random() * array.length)];
    }
    
    function blackjack() {
      let sum = 0;
      while (sum < 22) {
        sum += randomArrayElement(cards);
        alert(`Ваше число на данный момент ${sum}`);
        if (!confirm('Возьмете еще?')) {
          alert(`Вы спасовали ваше число ${sum}`);
          return;
        }
      }
      alert(`Вы проиграли ваше число ${sum}`);
    }
    
    blackjack();
    Ответ написан
    Комментировать