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

    0xD34F
    @0xD34F Куратор тега JavaScript
    Группируем данные:

    const grouped = Object.entries(arr.reduce((acc, n) => (
      (acc[n.id] ??= []).push(n.name),
      acc
    ), {}));

    Затем собираем html:

    document.body.insertAdjacentHTML('beforeend', grouped
      .map(([ k, v ]) => `
        <ul id="list-${k}">${v.map(n => `
          <li>${n}</li>`).join('')}
        </ul>`)
      .join('')
    );

    Или напрямую создаём элементы:

    document.body.append(...grouped.map(([ id, names ]) => {
      const ul = document.createElement('ul');
      ul.id = `list-${id}`;
    
      ul.append(...names.map(n => {
        const li = document.createElement('li');
        li.textContent = n;
        return li;
      }));
    
      return ul;
    }));
    Ответ написан
    Комментировать
  • Как скрыть часть телефонного номера звездочками?

    0xD34F
    @0xD34F Куратор тега JavaScript
    str.replace(/\d{3}-\d{2}/, '***-**')
    // или
    str.slice(0, 9) + '***-**' + str.slice(15)
    // или
    str.replace(/\d(?=\d*-)/g, '*')
    // или
    str.replace(/\d+(?=-)/g, m => '*'.repeat(m.length))
    // или
    str.replace(/(?<=\) ).{6}/, '***-**')
    // или
    str.match(/^.{9}|.{3}$/g).join('***-**')
    Ответ написан
    1 комментарий
  • Почему не работает сортировка массива?

    0xD34F
    @0xD34F Куратор тега JavaScript
    Вы не понимаете,...

    • ...как работают условные операторы:

      if (sortArray[i]) {

      Что если там 0? Тогда этот элемент обработан не будет - не попадёт в результирующий массив. О чём, кстати, и говорится в сообщении об ошибке, в возвращаемом вами отсортированном массиве элементов меньше, чем в исходном:

      expected [ Array(14980) ] to deeply equal [ Array(15000) ]

    • ...когда условные операторы следует применять - первый не нужен, элемент с индексом i всегда существует, так что засовывать в firstArray его следует без проверок.
    • ...как, имея индекс, проверить наличие соответствующего элемента в массиве.

    Исправленный вариант вашего кода.

    function pendulum(arr) {
      arr.sort((a, b) => a - b);
    
      const head = [];
      const tail = [];
    
      for (let i = 0; i < arr.length; i += 2) {
        head.push(arr[i]);
    
        if (i + 1 < arr.length) { // или if (arr.hasOwnProperty(i + 1)) {
          tail.push(arr[i + 1]);
        }
      }
    
      return [ ...head.reverse(), ...tail ];
    }


    А вообще, не надо тут никаких if'ов.
    const pendulum = arr => arr
      .sort((a, b) => a - b)
      .reduce((acc, n, i) => (acc[i & 1].push(n), acc), [ [], [] ])
      .flatMap((n, i) => i ? n : n.reverse());
    Ответ написан
    Комментировать
  • Как правильно удалять строки из таблицы?

    0xD34F
    @0xD34F Куратор тега JavaScript
    href="javascript:deleteRow(this);"

    Замените на onclick="deleteRow(this)".

    Или, просто уберите, и сделайте делегированный обработчик клика:

    document.querySelector('table').addEventListener('click', e => {
      e.target.closest('.btn')?.closest('tr').remove();
    });

    нашел другой вариант

    $('body').on('click', 'btn btn-warning', function() {
            $(this).parents('tr').remove();
        });


    НО проблема в том, что при нажатии удаляется полностью все строки, которые...

    Это не "вариант", а неработоспособный мусор - где точки перед именами классов?

    Что до удаления строк - этого не происходит. А вот страница перезагружается. Потому что href у ссылки пустой и не отменяете действие по умолчанию при клике. Надо так:

    $('table').on('click', '.btn.btn-warning', function(e) {
      e.preventDefault();
      $(this).closest('tr').remove();
    });

    Или, вместо пустой строки записывайте # ссылкам в href. Или, замените a на span, и стилизуйте его под ссылку:

    span.btn {
      text-decoration: underline;
      color: blue;
      cursor: pointer;
    }
    Ответ написан
    Комментировать
  • Как добавить генератор символа в строке, через каждые N символов?

    0xD34F
    @0xD34F Куратор тега JavaScript
    const getStr = length => Array
      .from({ length }, n => (
        n = Array(length).fill('.'),
        n[Math.random() * length | 0] = 'Q',
        n.join('')
      ))
      .join('\n');
    Ответ написан
    Комментировать
  • Почему не выводит правильно информацию о погоде?

    0xD34F
    @0xD34F Куратор тега JavaScript
    Потому что передаёте в sendRequesr вместо строки с городом соответствующий ей элемент <a>.
    Ответ написан
    3 комментария
  • Как установить значение в select multiple используя jquery?

    0xD34F
    @0xD34F Куратор тега JavaScript
    {"value":"[\"2b2df5f4-256d-402e-b074-c460ee394a2e

    Двойные кавычки перед [ видите? - value (days тоже) это строка, а не массив. Так что не хватает JSON.parse.
    Ответ написан
    1 комментарий
  • Как создать двухмерный массив данные из нескольких input JS?

    0xD34F
    @0xD34F Куратор тега JavaScript
    Сколько tbody у таблицы? Одна штука:

    document.querySelector('tbody').addEventListener('input', function() {
      const data = Array.from(
        this.children,
        tr => Array.from(tr.querySelectorAll('input'), input => input.value)
      );
    
      console.log(data);
    });

    Несколько:

    document.querySelector('table').addEventListener('input', e => {
      const { map, flatMap } = Array.prototype;
      const data = flatMap.call(
        e.currentTarget.tBodies,
        tbody => map.call(
          tbody.rows,
          tr => map.call(tr.cells, td => td.lastElementChild.value)
        )
      );
    
      console.log(data);
    });
    
    // или
    
    document.querySelector('table').addEventListener('input', function() {
      const numHeadRows = this.querySelectorAll('thead tr').length;
      const data = [];
    
      for (const input of this.querySelectorAll('tbody input')) {
        const td = input.parentNode;
        const iCol = td.cellIndex;
        const iRow = td.parentNode.rowIndex - numHeadRows;
        (data[iRow] ??= [])[iCol] = input.value;
      }
    
      console.log(data);
    });
    Ответ написан
    4 комментария
  • Как удалить одинаковые элементы но оставить один из них?

    0xD34F
    @0xD34F Куратор тега JavaScript
    О каких элементах идёт речь:

    const parent = document.querySelector('.top');
    const elements = parent.children;

    Удаляем:

    parent.replaceChildren(...Array.prototype.filter.call(
      elements,
      function({ textContent: n }) {
        return !this.has(n) && this.add(n);
      },
      new Set
    ));

    или

    const { size: numUnique } = Array.prototype.reduce.call(
      elements,
      (acc, n) => acc.add(elements[acc.size].innerText = n.innerText),
      new Set
    );
    
    for (; elements[numUnique]; parent.lastElementChild.remove()) ;

    или

    parent.innerHTML = Array
      .from(new Set(Array.from(elements, n => n.outerHTML)))
      .join('');

    или

    Object
      .values(Array
        .from(elements)
        .reduce((acc, n) => ((acc[n.innerText] ??= []).push(n), acc), {}))
      .forEach(n => n.forEach((m, i) => i && parent.removeChild(m)));

    или

    [...elements]
      .filter((n, i, a) => n !== a.find(m => m.innerText === n.innerText))
      .forEach(n => n.replaceWith());
    Ответ написан
    Комментировать
  • Как из массива объектов получить массив уникальных ключей?

    0xD34F
    @0xD34F Куратор тега JavaScript
    Коротко:

    const keys = [...new Set(arr.flatMap(Object.keys))];

    Длинно:

    const keys = arr.reduce((acc, n) => {
      for (const k in n) {
        if (n.hasOwnProperty(k) && !acc.includes(k)) {
          acc.push(k);
        }
      }
    
      return acc;
    }, []);
    Ответ написан
    Комментировать
  • Какие знания требуются для js trainee?

    0xD34F
    @0xD34F Куратор тега JavaScript
    Чё-то смеюсь. Раньше вы хотели быть джуном. То, что за прошедшие два с лишним года вы свои амбиции поумерили - это хорошо. Правда, не до конца - ну да это ничего, ещё через два года наверняка дозреете до осознания того факта, что не бывать вам программистом. Отсюда кстати и ответ на непосредственно заданный вопрос - вам никакие знания не требуются. Успокойтесь, и идите работать в такси.
    Ответ написан
    2 комментария
  • Double Linked List, почему функция не отрабаывает и как организовать remove?

    0xD34F
    @0xD34F Куратор тега JavaScript
    На вопрос "почему не отрабатывает" ответ смотрите в консоли - там есть соответствующее сообщение об ошибке.

    class DoublyLinkedList {
      constructor() {
        this.size = 0;
        this.head = null;
        this.tail = null;
      }
    
      add(value, index) {
        index ??= this.size;
    
        const next = this.searchByIndex(index);
        const prev = next ? next.prev : this.tail;
        const node = { value, next, prev };
    
        prev || (this.head = node);
        next || (this.tail = node);
    
        prev && (prev.next = node);
        next && (next.prev = node);
    
        this.size++;
      }
    
      _remove(node) {
        if (node) {
          node.prev || (this.head = node.next);
          node.next || (this.tail = node.prev);
    
          node.prev && (node.prev.next = node.next);
          node.next && (node.next.prev = node.prev);
    
          this.size--;
        }
      }
    
      removeByValue(value) {
        this._remove(this.searchByValue(value));
      }
    
      removeByIndex(index) {
        this._remove(this.searchByIndex(index, true));
      }
    
      searchByIndex(index, strict) {
        if (!(index >= 0 && index <= this.size - !!strict)) {
          throw 'invalid index';
        }
    
        let node = this.head;
    
        while (index--) {
          node = node.next;
        }
    
        return node;
      }
    
      searchByValue(value, startIndex = 0) {
        let node = this.searchByIndex(startIndex, true);
    
        while (node && node.value !== value) {
          node = node.next;
        }
    
        return node;
      }
    }
    Ответ написан
    Комментировать
  • Как сделать фильтрацию при помощи input type number?

    0xD34F
    @0xD34F Куратор тега JavaScript
    Куда пользователь забивает значение, кого надо проверять, и кого скрывать:

    const input = document.querySelector('input');
    const itemClass = 'word';
    const blockClass = 'block';

    Слушаем событие input, сравниваем значения, поднимаемся к блоку и переключаем его видимость:

    input.addEventListener('input', e => {
      const val = +e.target.value;
    
      document.querySelectorAll(`.${itemClass}`).forEach(n => {
        n.closest(`.${blockClass}`).hidden = +n.innerText < val;
      });
    });

    или

    .hidden {
      display: none;
    }

    input.oninput = function() {
      const val = Number(this.value);
    
      for (const n of document.getElementsByClassName(itemClass)) {
        let block = n;
        while (!(block = block.parentNode).classList.contains(blockClass)) ;
        block.classList.toggle('hidden', Number(n.textContent) < val);
      }
    };
    Ответ написан
    Комментировать
  • Как проверить существует ли приватный метод?

    0xD34F
    @0xD34F Куратор тега JavaScript
    try {
      eval('this.#' + name);
      return true;
    } catch(e) {
      return false;
    }
    Ответ написан
    1 комментарий
  • Как найти наибольшее значение по полю в объекте и вернуть его?

    0xD34F
    @0xD34F Куратор тега JavaScript
    function max(data, key = n => n) {
      const getVal = key instanceof Function ? key : n => n[key];
      let result = null;
    
      for (const n of data) {
        const val = getVal(n);
        result = (!result || result[1] < val) ? [ n, val ] : result;
      }
    
      return result?.[0];
    }

    const { text } = max(arr, n => n.text.length);
    const oldest = max(arr, 'age');
    Ответ написан
    Комментировать
  • Как удалить лишние столбцы в table с помощью jquery?

    0xD34F
    @0xD34F Куратор тега JavaScript
    Где и кого надо удалить:

    const tableSelector = 'здесь селектор вашей таблицы';
    const columnIndices = [ 8, 9, 10 ];
    
    const $rows = $(`${tableSelector} tr`);
    // или
    const { rows } = document.querySelector(tableSelector);

    Удаляем:

    $rows.each((_, n) =>
      $('> *', n)
        .filter(i => ~columnIndices.indexOf(i))
        .remove()
    );

    или

    $rows
      .children(`${columnIndices.map(n => `:nth-child(${-~n})`)}`)
      .detach();

    или

    Array.prototype.forEach.call(rows, function(n) {
      for (let i = n.cells.length; i--; this.has(i) && n.deleteCell(i)) ;
    }, new Set(columnIndices));

    или

    for (const { cells } of rows) {
      columnIndices.map(n => cells[n]).forEach(n => n?.remove());
    }

    или

    for (const n of rows) {
      n.replaceChildren(...Array.prototype.filter.call(
        n.cells,
        (_, i) => !columnIndices.includes(i)
      ));
    }
    Ответ написан
    Комментировать
  • Как получить массив чисел месяца вместе с днями недели?

    0xD34F
    @0xD34F Куратор тега JavaScript
    function getWeekdaysOfMonth(year, month) {
      const date = new Date(year, --month, 1);
      const result = [];
    
      while (date.getMonth() === month) {
        result.push(date.toLocaleString('ru-RU', {
          month: 'long',
          day: 'numeric',
          weekday: 'long',
        }));
        date.setDate(date.getDate() + 1);
      }
    
      return result;
    }
    
    
    const weekdaysOfDecember2020 = getWeekdaysOfMonth(2020, 12);

    UPD. Вынесено из комментариев:

    но как поступить если я не хочу забирать дни недели из стандартного объекта. а взять из их своего массива?

    const weekdays = [
      'воскресенье',
      'это понедельник',
      'а это вторник',
      'конечно же среда',
      'четверг',
      'пятница - прямо после четверга',
      'суббота, рабочая неделя окончена',
    ];
    
    const getWeekdaysOfMonth = (year, month) => Array.from(
      { length: new Date(year, month--, 0).getDate() },
      (n, i) => {
        const d = new Date(year, month, i + 1);
        return d.toLocaleString('ru-RU', {
          month: 'long',
          day: 'numeric',
        }) + ', ' + weekdays[d.getDay()];
      });
    
    
    const weekdaysOfFebruary2021 = getWeekdaysOfMonth(2021, 2);
    Ответ написан
  • Как из массива сделать вложенный объект?

    0xD34F
    @0xD34F Куратор тега JavaScript
    const result = arr.reduceRight((acc, n) => ({ [n]: acc }), {});

    или

    let result = {};
    for (let i = arr.length; i--;) {
      result = { [arr[i]]: result };
    }

    или

    const result = (function createObj(i) {
      return i < arr.length
        ? { [arr[i]]: createObj(-~i) }
        : {};
    })(0);
    Ответ написан
    Комментировать
  • Как получить src из тега picture?

    0xD34F
    @0xD34F Куратор тега JavaScript
    document.querySelector('.products__body').addEventListener('click', e => {
      const item = e.target.closest('.card-preview__item');
      if (item) {
        e.preventDefault();
        const { srcset } = item.querySelector('source');
        item.closest('.card').querySelector('.card-head__image source').srcset = srcset;
      }
    });
    Ответ написан
    1 комментарий
  • Почему не отрабатывает событие?

    0xD34F
    @0xD34F Куратор тега JavaScript
    • tagName:

      For DOM trees which represent HTML documents, the returned tag name is always in the canonical upper-case form.

      А теперь посмотрите, что вы у себя написали:

      if(str.tagName == 'ul') {

      } else if (str.tagName == 'li') {

      Кстати, а почему str, что за странный выбор имени? Там же элемент, а не строка.

    • Вместо элемента добавляется строка:

      elem.append('li');

    • Крайне странное назначение обработчика клика:

      for (let el of strLi) {
          el.addEventListener('click',func);
      };

      Во-первых - зачем каждый раз добавлять всем? Хорошо, что хоть объявление func вынесено за пределы текущей функции, иначе бы при каждом клике всем существующим li добавлялся новый обработчик.

      Во-вторых - пока не кликните по li, на свежесозданных li клик обрабатываться не будет (касается и тех, что изначально существуют).

      В-третьих - а на хрена оно надо? Вы же уже обрабатываете клик по li - так зачем назначать отдельный обработчик клика? То, что делаете в func, вполне можно делать прямо тут.


    А вообще, исправлять существующий код я бы не стал. Лучше его вырезать полностью и написать другой, получится гораздо проще и короче:

    document.querySelector('ul').addEventListener('click', e => {
      const t = e.target;
      const ct = e.currentTarget;
      t.insertAdjacentHTML('beforeend', ct === t ? '<li>text</li>' : '!');
    });
    Ответ написан
    Комментировать