Задать вопрос
  • Почему переданный в функцию параметр меняется?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Потому, что Number.MAX_SAFE_INTEGER в JavaScript это 2^53 - 1
    9007199254740991 // максимальное безопасное целое
    17848907461544179 // ваш ID больше – происходят округления


    TL&DR; передавайте такие post_id в кавычках, как строки.
    Ответ написан
    3 комментария
  • Почему не отображаются параметры URL?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Метод pushState() браузерного History API:
    const url = new URL(window.location);
    url.searchParams.set('qna', 'habr');
    window.history.pushState({}, '', url);
    // в адресной строке теперь ?qna=habr
    Ответ написан
    1 комментарий
  • Как разобраться с this в javascript окончательно?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Вот была неплохая статья на Хабре с попытками разобраться с this в JavaScript.
    • Первый случай, метод объекта – при непосредственном получении и вызове делает этот объект this'ом.
    • Второй же случай — функция, внутри другой («да»), не стрелочная, «нет», «нет» ... «нет» — this равен глобальному объекту. Если включить строгий режим, вместо Window получим undefined.

    Статья не столько объясняет (объясняет под спойлерами Комментарий), сколько предлагает алгоритм рассуждений, «таблицу умножения» для запоминания — чтобы предсказывать значение this.
    Ответ написан
    7 комментариев
  • Как вызвать функци после setTimeout?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Как-нибудь так:
    const delay = seconds => new Promise(res => setTimeout(res, 1000 * seconds));
    
    const parse = async () => {
      // ...
    };
    
    const main = async () => {
      await delay(10); // подождать 10 секунд
      await parse();   // что-то там спарсить
      reloadPage();    // перезагрузить страницу
    };
    
    window.addEventListener('load', main);
    Ответ написан
    7 комментариев
  • Из-за чего элементы массива возвращают 3?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Объявленная через устаревший var переменная i всплывает наверх, видна отовсюду и поёт похабные частушки сохраняет видимое для всех созданных функций единое значение 3 по окончании цикла. Это не то, что задумано.

    Использование спортивных, современных const и let чудесным образом исправляет досадное недоразумение:
    const arr = []; // ведь сам массив не планируется заменять
    
    for (let i = 0; i <= 2; i++) { // главное: i теперь видна только внутри цикла
       arr[i] = function () {
          console.log(i);
       };
    }
    
    arr[0](); // 0
    arr[arr.length - 1](); // 2
    в исходном коде только лишь заменили var на const (не так важно) и let (вот это изменило всё!).

    Можно использовать и стрелочную функцию:
    const arr = [];
    for (let i = 0; i <= 2; i++) {
       arr[i] = () => console.log(i);
    }
    Ответ написан
    Комментировать
  • Как элементы массива сделать значениями объекта?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Короткий способ: создание объекта из пар [ключ, значение] методом fromEntries():
    Object.fromEntries(arr.map((v, i) => [i + 1, v]))

    как это работает
    Из исходного массива методом map() создаётся новый, где каждый элемент это тоже массив:
    [ [1, 'a'], [2, 'b'], ... ]
    Такой массив массивов годится для передачи в Object.fromEntries() для получения искомого объекта.
    Ответ написан
    Комментировать
  • Нужно обьект записать в БД MySQL, как сделать?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    попробуйте так
    - let query = "INSERT INTO user_records.users (id, name, username, email, city, phone) values?";
    + let query = `INSERT INTO user_records.users
    +   (id, name, username, email, city, phone)
    +   VALUES (?, ?, ?, ?, ?, ?)
    + `;
    Ответ написан
  • Правильный синтаксис для такой команды?

    Обратные кавычки ` `, которыми окружено название таблицы, в шелле означают, что надо выполнить команду внутри них.

    Если внутри двойных кавычек " ... ", то экранируйте эти обратные кавычки: ...IF NOT EXISTS \`stack-table\`

    В данном случае прослойка с bash даже и не нужна, можно сразу выполнять команду mysql:
    docker exec stack-mysql \
      mysql -u root -proot -h mysql \
        -e 'CREATE DATABASE IF NOT EXISTS `stack-table`';
    В одинарных кавычках экранировать обратные тики не нужно.
    Ответ написан
  • Как вставить тег br, чтобы числа выводились с новой строки?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Можно таблицу собрать из этих чисел:
    const arr = [ 1, 2, 3, 4, 5, 6, 7] ;
    const html = `<table><tbody>
    ${ arr.map(n => `<tr><td>${n}</td></tr>`).join() }
    </tbody></table>`;
    
    document.write(html); // вообще так лучше не делать

    правильнее

    ..создать элемент, в него засунуть HTML и элемент вставить в DOM-дерево
    const table = document.createElement('table');
    const rows = arr.map(n => `<tr><td>${n}</td></tr>`).join();
    table.innerHTML = rows;
    document.body.appendChild(table);

    Ответ написан
    Комментировать
  • Почему везде используют const вместо let в JS?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Редактор кода домой не отпустит, пока переменную, которую нигде не изменяют,
    не объявить вместо let — const )

    Иммутабельность должна быть явной!

    При чтении кода гораздо удобнее для понимания изначально знать, что от константы сюрпризов не ждать.
    А переменную стоит посмотреть внимательнее: где, как, зачем и на что меняют.
    Ответ написан
    Комментировать
  • Как группировать объекты по заданному свойству с помощью reduce?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Обращение к lodash.has() тоже навеное, недопустимо в задании?

    Ошибка в том, что ключом назначаете criteria,
    а надо значение этого свойства очередного юзера: key = user[criteria]
    – так, если в criteria строка "mark", переменная key получит значение 3 у первого юзера.

    spoiler
    в одну нечитаемую строку:
    const groupBy = (usersArr, criteria) => usersArr.reduce((acc, user) => ((acc[user[criteria]] ??= []).push(user), acc), {});
    Ответ написан
  • Как удалить гласные в строке?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Под капотом движок регулярок довольно большой и «тяжёлый». В этой задаче можно обойтись массивами и их эффективными методами.

    Разбить начальную строку на массив букв, отфильтровать его, сохранив только не-гласные, склеить:
    function disemvowel(str) {
      const vowels = ['a', 'e', 'i', 'o', 'u'];
      return str
        .split('')
        .filter(char => !vowels.includes(char))
        .join('');
    }
    
    console.log(disemvowel('Twinkle, twinkle, little star, How I wonder what you are.'));
    // Twnkl, twnkl, lttl str, Hw I wndr wht y r.
    Ответ написан
    1 комментарий
  • Как распределить значение по ячейкам примерно равномерно?

    sergiks
    @sergiks Куратор тега Алгоритмы
    ♬♬
    Для каждой ячейки известна её оставшаяся до потолка 1 «ёмкость».

    Сложить ёмкости = capacity вместимость всего массива.
    Если X > capacity — «невпихуемо!» — задача не имеет решения.

    Коэффициент k = X / capacity меньше или равен 1.
    Идти по ячейкам, откусывать от X в очередную кусочек, пропорционально ёмкости этой ячейки с коэфф. k.

    Так в каждую доложат пропорционально её ёмкости, сглаживая неравномерность заполнения.
    шесть строк на JS
    const spread = (value, arr) => {
      const CELL_MAX = 1;
      const sum = arr.reduce((acc, c) => acc + c);
      const capacity = arr.length * CELL_MAX - sum;
      if (value > capacity) throw new Error("Value won't fit");
      const k = value / capacity;
      return arr.map(el => el + (CELL_MAX - el) * k);
    }
    
    spread(0.2, [ 0.1, 0.1 ]) // [ 0.2, 0.2 ]
    spread(0.2, [ 0.1, 0.99 ]) // [ 0.29780219780219785, 0.9921978021978022 ]
    Ответ написан
    2 комментария
  • Как отфильтровать ненужные записи?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Object.values(data)
      .flatMap(({ person }) => Object.values(person))
      .filter(({ age }) => age === 18)
    
    // [ { name: "alex", age: 18 } ]
    Ответ написан
    2 комментария
  • Как сверить id из двух массивов?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    const hasItemById = (arr, searchId) => arr.some(({ id }) => id === searchId);
    
    hasItemById(arr, arr2[0].id) // true
    hasItemById(arr, 100) // false
    Ответ написан
    Комментировать
  • Возникла проблема, не могу понять как выполнить условие задачи?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    забыли уменьшать счётчик attempt на каждой итерации

    -    while(remainingLetters > 0 && attempt > 0) {
    +    while(remainingLetters > 0 && attempt-- > 0) {
    Ответ написан
  • Как возвести в квадрат каждый элемент в массиве?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Минутка лишних усложнений и новых концепций.

    В JavaScript примитивные значения (числа, например) копируются/передаются «значением», не сохраняя никакой связи с оригиналом. А объекты (например, массив) передаются «ссылкой» на оригинал.

    Судя по неудачной попытке, был расчёт, что изменив elem, изменится и его «оригинал» – элемент массива. Но нет. Число возвели в квадрат, но в массиве всё осталось по-прежнему.

    Будь elem не числом, а объектом, трюк сработал бы.
    пример
    let arr = [ {x: 1},  {x: 2},  {x: 3},  {x: 4},  {x: 5} ];
    
    for (let elem of arr) {
      elem.x = elem.x ** 2;
    }
    // [ {"x": 1}, {"x": 4}, {"x": 9}, {"x": 16}, {"x": 25} ]


    А в случае с примитивами (числом, строкой) надо как-то вложить квадратное значение обратно в массив в нужную ячейку. Этого-то и не хватает в коде.
    Ответ написан
    Комментировать
  • Не могу найти ошибку в условии, в консоли выводит 0, что делать?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Пара ошибок:
    1. for .. in перебирает имена свойств объекта ('a', 'b', 'c', ...)
      а тут требуются значения (10, 20, 30, ...) – значения перебирает for .. of
    2. значения — числа. Чтобы забрать первую букву (цифру) нужна строка. Поэтому надо каждое значение сначала сделать строкой. Например, методом toString():
      const num = 10; // число
      num.toString() // результат "10" – строка текста
    Поправьте эти два момента и всё наладится.

    Можно и в одну нечитабельную строку:
    Object.values(obj).reduce((acc, c) => acc + c.toString().match(/^[12]/), 0) // 2
    но здесь используется тяжёлый механизм регулярных выражений, хотя вполне можно без него; и неочевидное приведение типа Boolean к Number ради краткой записи.
    Ответ написан
    Комментировать
  • Как добраться до вложенного объекта в массиве?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Буквально в лоб добраться до пола первой подруги или друга первого юзера можно так:
    users[0].friends[0].gender

    Для решения задачи сначала нужно вытащить из каждого элемента массива (из каждого user) только его свойство friends (массив). Был объект user, стал только его массив friends. Методом map()

    Причём, в массиве friends методом filter() надо оставить только тех, где gender === 'female'

    Так из начального массива users получится массив массивов – иногда пустых, иногда с девушками.
    Массив массивов сделать просто-массивом, без пустышек, можно методом flat()

    Ну а потом можно эти два последовательных метода map(fn).flat() заменить на один, делающий то же самое, flatMap(fn)

    spoiler
    users.flatMap(({ friends }) => friends.filter(({ gender }) => gender === 'female'));
    
    // [ {"name":"Mira","gender":"female"}, {"name":"Aria","gender":"female"}, {"name":"Keit","gender":"female"} ]
    Ответ написан
    1 комментарий
  • Как улучшить производительность данного кода?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    не нужно на каждой позиции составлять окно заново.

    Заполнили окно в самой левой позции. Посчитали его "кардинальность" (число уникальных).

    Далее на каждом шаге удаляется 1 элемент слева и добавляется 1 элемент справа. Смотрим, изменилась ли кардинальность:
    - удаляемый элемент ещё есть в оставшихся? Нет – значит мы уменьшили кардинальность на 1.
    - то же с добавляемым: уже есть такой в середине окна? Нет – значит, увеличили кардинальность на 1.

    Такое решение прокатило и по перформансу, хотя там есть вложенные мини-циклы для поиска удаляемого/добавляемого значений в остающемся огрызке. Наверняка, есть более элегантные решения.
    spoiler
    function countContiguousDistinct(k, arr) {
      let cardinality = 0;
      for (let i = 0; i < k; i++) {
        if (i === arr.indexOf(arr[i])) cardinality++;
      }
      const result = [cardinality];
      
      const isNotInWindow = (value, arr, start, finish) => {
        for (let j = start; j < finish; j++) {
          if (arr[j] === value) return false;
        }
        return true;
      }
      
      for (let i = 0; i < arr.length - k; i++) {
        const L = arr[i];
        const R = arr[i + k];
        if (L !== R) {
          if (isNotInWindow(L, arr, i + 1, i + k)) cardinality--;
          if (isNotInWindow(R, arr, i + 1, i + k)) cardinality++;
        }
        result.push(cardinality);
      }
      
      return result;
    }
    Ответ написан
    Комментировать