Задать вопрос
Ответы пользователя по тегу JavaScript
  • Как отследить изменения полей?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    на обоих полях слушать событие "input" — когда что-то меняется.

    Обработчик этих событий один, общий.
    Он проверяет, заполнены ли оба поля,
    и добавляет/убирает атрибут disabled на кнопке
    или меняет класс цвета кнопки.
    Ответ написан
  • Как найти минимальное значение в строках матрицы?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Почти правильно решили.
    В коде надо четко понимать, что есть что.

    Math.min() возвращает минимальное значение среди переданных ему.
    Т.е. надо в скобки Math.min() положить несколько значений, из которых он выберет одно, минимальное.

    В задании просят найти минимальное в каждой строке. Значит, в Math.min() надо передать все значения из очередной строки.

    Обычно Math.min() принимает варианты через запятую: Math.min(1, 3, 5), но у нас каждая строка это массив вроде [1, 3, 5] Массив удобно «распаковать» с помощью трёх точек ... (так называемый оператор расширения). Есть очередная строка в массиве arr – передать её в Math.min(...arr) – вернёт минимальное значение.

    Сейчас внешний цикл for() перебирает у вас как раз строки двумерного массива. То, что надо.
    Вложенный цикл уже и не нужен.

    P. S. минимальное значение можно искать и перебором, со вторым, вложенным циклом for() как у вас. Это длиннее, но тоже работает, особенно на больших объёмах данных. В таком варианте надо бы убрать Math.min() в конце.

    В каждой итерации инициализировать s не в 0, а в константу Number.POSITIVE_INFINITY – больше её точно ничего не будет, все значения окажутся меньше. А дальше сравнивать текущее значение s с очередным числом из строки. И если очередное оказалось меньше — переназначать s это значение, очередной найденный минимум.

    spoiler
    document.write(
      mass.map(row => Math.min(...row)).join(', ')
    ); // 2, 4, 7
    Ответ написан
    Комментировать
  • Почему выводит пустой цвет фона у элемента?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    red.style.backgroundColor – берётся элемент red,
    его свойство style содержит инлайновые стили, назначенные именно этому элементу. Напрямую.

    Не унаследованные через листы стилей, предопределённые браузером, назначенные браузерным расширением.

    Напрямую свойство в style:
    const el = document.createElement('div');
    div.style.backgroundColor = "red";
    
    div.style.backgroundColor // "red"


    Добавленный класс:
    div.classList.add("green-text"); // CSS .green-text { color: green; }
    
    div.style.color // ""

    Прямо в разметке
    <p style="font-weight: bold">Bold</p>
    document.querySelector('p').style.fontWeight // "bold"

    Унаследованный от родителя
    <p style="font-weight: bold">
      <span>Bold</span>
    </p>

    document.querySelector('span').style.fontWeight // ""
    Ответ написан
    Комментировать
  • Как выполнить код?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Обернуть в функцию:
    let retryCount = 0;
    const retryMax = 3;
    const url = 'https://example.com/api/method';
    
    const getData = () => {
      $.get(url, data => {
        // ...
      }).fail(() => {
        if (++retryCount <= retryMax) {
          setTimeout(getData, 1000); // через секунду
        } else {
          console.error('Так и не получилось');
        }
      });
    };
    
    getData();
    Ответ написан
    Комментировать
  • Как делают такие интерфейсы и навешивают события?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Два варианта, которые не видны в разметке:
    1. element.addEventListener('click', handlerFunction);

    2. делегирование событий: слушают события не на самих элементах, а выше, на общем родителе. Тоже, скорее, не через onclick="handler" в разметке, а через addEventListener()
    Ответ написан
    Комментировать
  • Как слелать функцию подсчета?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Пройтись по участникам команды, собирая объект, где ключи – названия профессий, значения – аккумулирующиеся суммы затрат на соотв. профессию. Типа, { Progger: 100, Tester: 200 }

    Затем остаётся только сложить значения всех свойств этого объекта для тотала по всей комманде, и переименовать ключи, дописав в начале им "totalBudget":
    const calculateTeamFinanceReport = (salaries, team) => {
      const bySpec = team.reduce((acc, { specialization: spec }) => {
        if (!Object.hasOwn(acc, spec)) acc[spec] = 0;
        const { salary, tax } = salaries[spec];
        const k = 1 + parseFloat(tax) / 100;
        acc[spec] += salary * k;
    
        return acc;
      }, {});
    
      const totalBudgetTeam = Object.values(bySpec).reduce((acc, c) => acc + c);
      const result = Object.fromEntries(Object.entries(bySpec).map(([key, value]) => ['totalBudget' + key, value]));
    
      return { totalBudgetTeam, ...result };
    };
    
    calculateTeamFinanceReport(salaries, team);
    // { totalBudgetTeam: 3350, totalBudgetProgger: 1150, totalBudgetTester: 2200 }
    Для разбора процентов удобна функция parseFloat() – она читает цифры с начала строки, сколько может. И игнорирует буквы после. parseFloat('15.5%') === 15.5
    Ответ написан
    Комментировать
  • Как перебрать методы объектов в массиве?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    const arrayOfObjects = [
      { student: 'Dmitriy', runLab () {return 1;}},
      { student: 'Andrew', runLab () {return 2;}},
      { student: 'Mellisa', runLab () {return 3;}},
      { student: 'Ann', XrunLab () {return 4;}},
    ];
    
    function gradeLabs(labs, expectedResult = 1) {
      labs.forEach(({ student, runLab }) => {
        try {
          const result = runLab();
          if (result === expectedResult) {
            console.log('Student %s has PASSED the test', student);
          } else {
            console.error('Student %s has FAILED the test', student);
          }
        } catch (e) {
          console.error('Student: %s has FAILED the test. Error thrown: %o', student, e);
        }
      });
    }
    
    gradeLabs(arrayOfObjects, 1);
    Ответ написан
    2 комментария
  • Как найти слова по вертикали и змейкой?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Найти первую букву (может, в нескольких местах окажется).
    Есть её X и Y.
    Для каждого варианта: проверять буквы сверху, снизу, справа, слева на предмет соответствия следующей искомой.

    Уточнить бы правила: можно ли смотреть налево от текущей буквы. Можно ли дважды проходить через одну и ту же.
    Ответ написан
    Комментировать
  • Как удалить html пробел через js и заменить на обычный?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    В консоли на этой странице можно выполнить:
    document.querySelectorAll('code.html.hljs.xml')
      .forEach(el => el.innerText = el.innerText.replaceAll(/&nbsp;/gi, ' '));
    Ответ написан
  • Как перевести число в hex с фиксированной длиной строки?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    см. метод строки padStart()

    dec.toString(16).padStart(64, '0')
    Ответ написан
    1 комментарий
  • Решил задачу, но вопрос насколько верное решение выбрал?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Ревью
    В вашем решении можно улучшить мелочи:
    1. переменная arr нужна только внутри цикла, лучше её туда и поместить. В большом коде проще будет разобраться, когда ограничена область видимости созданных переменных. const вместо let уместнее, т.к. внутри цикла значение key не меняется, да и arr тоже:
    for (const key in a14) {
      const arr = a14[key];
      // ...
    }


    2. т.к. просят «через пробел» – удобнее всего складывать значения в массив, а потом его .join(' ') – это избавляет от проблемы лишнего пробела, да и мухи данные отдельно, оформление отдельно.

    3. вместо innerHTML лучше innerText, т.к. выводимое не содержит разметки, и зачем заставлять браузер пытаться разбирать его как HTML.

    4. вешать слушателя события клика лучше через addEventListener:
    - document.querySelector('.b-14').onclick = f14;
    + document.querySelector('.b-14').addEventListener('click', f14);


    Альтернатива
    На какой стадии обучения выдали это задание, мне неизвестно.
    Но раз там есть и объект a14, то может, слышали про Object.values().
    А раз в задании говорят про массивы, то, может, знакомы методы map() и join()?

    Можно решить так:
    const f14 = () => document.querySelector('.out-14') // элемент для вывода результата
      .innerText = Object.values(a14) // массив массивов [ [1, 2, 23], [3, 4, 5], ... ]
        .map(arr => arr[0]) // вместо каждого под-массива, его первый элемент
        .join(' '); // склеить в строку через пробел
    Ответ написан
    1 комментарий
  • Чем можно сгенерировать множество pdf?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Puppeteer (кукловод на англ.)

    запустить «безголовый» браузер Chromium, который отрендерит страницу с данными. И забрать её в PDF.

    Пример сохранения страницы сайта в PDF.
    Ответ написан
    Комментировать
  • Как создать функцию, которая принимает текст, разделённый переносами строк и возвращает новый текст, в котором каждая строка обернута в тег?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Разбить такой текст по символу новой строки в массив.
    Каждую строку обернуть в тег.
    Снова склеить строки в одну, с помощью символа новой строки:
    text.split('\n')
      .map(row => `<p>${row}</p>`)
      .join('\n');
    Ответ написан
    Комментировать
  • Каков шанс выпадения нужного числа?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    random(6) возвращает целое: 1, 2, 3, 4, 5 или 6 – с равной вероятностью.
    Как игральные кости (кубики).

    Чтобы reduce/length дал единицу,
    нужно, чтобы все шесть выпали именно единицы:
    (1 + 1 + 1 + 1 + 1 + 1) / 6 == 1

    Вероятность шести единиц
    1/6 * 1/6 * 1/6 * 1/6 * 1/6 * 1/6  = 1 / 6^6 = 0,00002143347051
    = 2 тысячные процента. Всего ничего.
    Ответ написан
    Комментировать
  • Как удалить все текстовые элементы со страницы через js?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    можно использовать treeWalker:

    Но это вообще все текстовые узлы на странице удалит. Формулируйте желания точнее.
    Ответ написан
    Комментировать
  • Как посчитать сумму каждого элемента многомерного массива?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    [[1, 2, 3],[4, 5, 6],[7, 8, 9]].map(arr => arr.reduce((acc, c) => acc + c)) 
    // [ 6, 15, 24 ]


    Объяснение
    Каждый элемент внешнего массива трансформируется в число:
    [
      [1, 2, 3] --> 6
      [4, 5, 6] --> 15
      [7, 8, 9] --> 24
    ]
    — это операция map(): каждый-в-каждый.

    Теперь суть каждого такого преобразования. Из массива получить единственное значение — это reduce()

    Сложить все элементы массива и вернуть сумму. Аккумулятором будет эта самая сумма. Очередное значение складывать с накопленным аккумулятором и возвращать сумму.
    reduce( (accumulator, current) => accumulator + current )
    с обычной функцией
    reduce(
      function(accumulator, current) {
        return accumulator + current;
      }
    )

    Начальное значение аккумулятора даже не обязательно указывать вторым аргументом, т.к. в таком случае сразу берётся значение первого элемента. В деле сложения это вполне устраивает.
    Ответ написан
    Комментировать
  • Как сложить все значения массива по квартально?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    добавить поле квартала: год-квартал, что-то типа
    data.map(({ day, ...rest }) => {
      const quarter = ['I', 'II', 'III', 'IV'][Math.floor((+day.substring(5, 7) - 1) / 3)];
      const year = day.substring(0, 4);
      const hash = `${year}-${quarter}`; // "2022-IV"
      return { hash, day, ...rest };
    })
    Результат
    [
      {
        "hash": "2021-III",
        "day": "2021-07-23T00:00:00",
        "speed": 3283,
        "distance": 3283,
        "wagons": 1
      },
      {
        "hash": "2021-III",
        "day": "2021-09-26T00:00:00",
        "speed": 1879,
        "distance": 1879,
        "wagons": 1
      },
      {
        "hash": "2022-I",
        "day": "2022-03-11T00:00:00",
        "speed": 10372,
        "distance": 15558,
        "wagons": 3
      },
      {
        "hash": "2022-III",
        "day": "2022-07-25T00:00:00",
        "speed": 455,
        "distance": 455,
        "wagons": 1
      },
      {
        "hash": "2022-III",
        "day": "2022-09-24T00:00:00",
        "speed": 3720.0666666666666,
        "distance": 18632,
        "wagons": 11
      },
      {
        "hash": "2022-IV",
        "day": "2022-10-01T00:00:00",
        "speed": 55944.81598981719,
        "distance": 1227358,
        "wagons": 805
      },
      {
        "hash": "2022-IV",
        "day": "2022-11-01T00:00:00",
        "speed": 35877.33829052166,
        "distance": 6621346,
        "wagons": 5528
      },
      {
        "hash": "2022-IV",
        "day": "2022-12-01T00:00:00",
        "speed": 39757.51849326638,
        "distance": 9322141,
        "wagons": 7258
      },
      {
        "hash": "2023-I",
        "day": "2023-01-01T00:00:00",
        "speed": 16726.83149608712,
        "distance": 1022607,
        "wagons": 794
      }
    ]
    Ответ написан
  • Как сложить все значения массива по полю месяца?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Стоит включить и год, и месяц в хэш, а то мало ли, более 1 года попадёт в выборку.
    const props = ['speed', 'distance', 'wagons'];
    
    const result = data.reduce((acc, c) => {
      const yearMonth = c.day.substring(0, 7); // '2022-03'
      props.forEach(prop => {
        acc[prop][yearMonth] = (acc[prop][yearMonth] ?? 0) + c[prop];
      });
      return acc;
    }, Object.fromEntries(props.map(prop => [prop, {}])));
    Результат
    {
      "speed": {
        "2022-09": 22452,
        "2022-10": 65668.58282444967,
        "2022-11": 6397.635863857564
      },
      "distance": {
        "2022-09": 68752,
        "2022-10": 1119233,
        "2022-11": 289732
      },
      "wagons": {
        "2022-09": 26,
        "2022-10": 427,
        "2022-11": 176
      }
    }


    Другой вариант:
    const hashMap = data.reduce((acc, { day, ...rest }) => {
      const hash = day.substring(0, 7);
      if (Object.hasOwn(acc, hash)) {
        Object.keys(rest).forEach(prop => acc[hash][prop] += rest[prop]);
      } else {
        acc[hash] = { day: hash, ...rest };
      }
    
      return acc;
    }, {});
    
    const result = Object.values(hashMap);
    Результат
    [
      {
        "day": "2022-09",
        "speed": 22452,
        "distance": 68752,
        "wagons": 26
      },
      {
        "day": "2022-10",
        "speed": 65668.58282444967,
        "distance": 1119233,
        "wagons": 427
      },
      {
        "day": "2022-11",
        "speed": 6397.635863857564,
        "distance": 289732,
        "wagons": 176
      }
    ]
    Ответ написан
    3 комментария
  • Как получить все элементы массива по data-атрибутам?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    data-атрибуты должны непременно начинаться именно с "data-" с дефисом.

    Ответ написан
    3 комментария