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

    0xD34F
    @0xD34F Куратор тега JavaScript
    const obj = [...str.matchAll(/([^?&]+)=([^&]+)/g)]
      .reduce((acc, [ , k, v ]) => (
        k.endsWith('[]')
          ? (acc[k.slice(0, -2)] ??= []).push(v)
          : acc[k] = v,
        acc
      ), {});

    или

    const params = new URLSearchParams(str);
    const reg = /\[\]$/;
    const obj = Object.fromEntries(Array.from(
      new Set(params.keys()),
      n => [
        n.replace(reg, ''),
        params[reg.test(n) ? 'getAll' : 'get'](n),
      ]
    ));

    или

    const obj = str.split('?').pop().split('&').reduce((acc, n) => {
      let [ k, v ] = n.split('=');
      const isArr = k.slice(-2) === '[]';
      k = k.substring(0, k.length - isArr * 2);
      const target = (isArr ? (acc[k] = acc[k] || []) : acc);
      target[isArr ? target.length : k] = v;
      return acc;
    }, {});
    Ответ написан
  • Как правильно отфильтровать данные?

    0xD34F
    @0xD34F Куратор тега JavaScript
    const result = arr.filter(n => n.sessions.every(m => m.startDate !== sessionStartDate));

    или

    const result = [];
    
    OUTER:
    for (const n of arr) {
      for (const m of n.sessions) {
        if (m.startDate === sessionStartDate) {
          continue OUTER;
        }
      }
    
      result.push(n);
    }
    Ответ написан
    Комментировать
  • Как выбрать объекты в массиве по индексу другого массива?

    0xD34F
    @0xD34F Куратор тега JavaScript
    Какое свойство проверяем: const key = 'strategy';.

    Достаём объекты:

    const result = arr.filter(function(n) {
      return this.has(n[key]);
    }, new Set(arr2));

    или

    const result = arr2.flatMap(((values, n) => values[n] ?? []).bind(
      null,
      arr.reduce((acc, n) => ((acc[n[key]] ??= []).push(n), acc), {})
    ));

    или

    const result = [];
    for (const n of arr) {
      for (const m of arr2) {
        if (m === n[key]) {
          result.push(n);
          break;
        }
      }
    }

    или

    const result = [];
    for (let i = 0; i < arr.length; i++) {
      if (~arr2.indexOf(arr[i][key])) {
        result[result.length] = arr[i];
      }
    }

    или

    const result = (function get(i, n = arr[i]) {
      return n
        ? [].concat(arr2.includes(n[key]) ? n : [], get(-~i))
        : [];
    })(0);
    Ответ написан
    1 комментарий
  • Как из массива объектов, вытащить значение по ключу?

    0xD34F
    @0xD34F Куратор тега JavaScript
    Одно значение (первое):

    const val = arr.find(n => n.hasOwnProperty(key))?.[key];

    Все, что есть:

    const vals = arr.reduce((acc, n) => (n.hasOwnProperty(key) && acc.push(n[key]), acc), []);
    Ответ написан
    Комментировать
  • Как сравнить 2 списка по data и по клику при совпадении удалять li которые совпадают?

    0xD34F
    @0xD34F Куратор тега JavaScript
    const key = 'number';
    const attr = `data-${key}`;
    const attrSelector = `[${attr}]`;

    document.addEventListener('click', e => {
      const value = e.target.closest(attrSelector)?.dataset[key];
      if (value) {
        document.querySelectorAll(`[${attr}="${value}"]`).forEach(n => n.remove());
      }
    });
    
    // или
    
    const elems = [...document.querySelectorAll(attrSelector)];
    const onClick = ({ currentTarget: { attributes: { [attr]: { value } } } }) =>
      elems.length -= elems.reduce((acc, n, i, a) => (
        a[i - acc] = n,
        acc + (n.getAttribute(attr) === value && !n.replaceWith())
      ), 0);
    
    elems.forEach(n => n.addEventListener('click', onClick));
    Ответ написан
    Комментировать
  • Как сравнивать массивы не в порядке элементов?

    0xD34F
    @0xD34F Куратор тега JavaScript
    function haveSameValues(arr1, arr2) {
      if (arr1.length !== arr2.length) {
        return false;
      }
    
      const count = new Map;
      arr1.forEach(n => count.set(n, -~count.get(n)));
      arr2.forEach(n => count.set(n, ~-count.get(n)));
    
      for (const n of count.values()) if (n) {
        return false;
      }
    
      return true;
    }

    haveSameValues(
      [ 'hello, world!!', 0, 0, 0, 1, 1, false, false ],
      [ false, false, 1, 1, 0, 0, 0, 'hello, world!!' ]
    ) // true
    
    haveSameValues(
      [ 1, 2, 3 ],
      [ 3, 2, 2 ]
    ) // false
    
    haveSameValues(
      [],
      []
    ) // true
    Ответ написан
    Комментировать
  • Как изменить код, чтобы в массиве объектов не попадались одинаковые элементы?

    0xD34F
    @0xD34F Куратор тега JavaScript
    Выдёргиваем из элементов массив текстов, уникализируем его, собираем массив объектов:

    const arr = Array.from(
      new Set(Array.from(document.querySelectorAll('.shop_name'), n => n.innerText)),
      n => ({ name: n })
    );

    Или, собираем объект, где ключами будут тексты элементов, а значениями объекты, затем выдёргиваем из полученного объекта массив значений:

    const arr = Object.values(Array.prototype.reduce.call(
      document.getElementsByClassName('shop_name'),
      (acc, { textContent: name }) => (acc[name] ??= { name }, acc),
      {}
    ));
    Ответ написан
    3 комментария
  • Как сделать вывод данных из объекта в определённом порядке?

    0xD34F
    @0xD34F Куратор тега JavaScript
    Перезаписываем разметку:

    wrapper.innerHTML = Array
      .from(word.value, n => obj[n] ? `<img src="${obj[n]}">` : '')
      .join('');

    Или, удаляем существующие узлы и создаём новые:

    for (let n = null; n = wrapper.lastChild; n.remove()) ;
    
    for (const n of word.value) {
      if (obj.hasOwnProperty(n)) {
        const img = new Image;
        img.src = obj[n];
        wrapper.append(img);
      }
    }
    
    // или
    
    wrapper.replaceChildren(...Array.prototype.reduce.call(
      word.value,
      (acc, n) => (
        obj[n] && ((acc[acc.length] = new Image).src = obj[n]),
        acc
      ),
      []
    ));

    Или, удаляем лишние/создаём недостающие узлы:

    while (word.value.length < wrapper.children.length) {
      wrapper.removeChild(wrapper.lastElementChild);
    }
    
    while (word.value.length > wrapper.children.length) {
      wrapper.appendChild(document.createElement('img'));
    }
    
    Array.prototype.forEach.call(wrapper.children, (n, i) => {
      const src = obj[word.value[i]];
      if (!(n.hidden = !src)) {
        n.src = src;
      }
    });

    Конечно, вопрос был про другое, но это просто чудовищно:

    let obj = {
        'а': 'https://github.com/itsFide/converter/blob/master/img/а.png?raw=true',
        'А': 'https://github.com/itsFide/converter/blob/master/img/а.png?raw=true',
        'б':'https://github.com/itsFide/converter/blob/master/img/б.png?raw=true',
        ...

    Давайте-ка сократим:

    const obj = Object.fromEntries(Array.prototype.flatMap.call(
      'абвгдеёжзийклмнопрстуфхцчшщъыьэюя', n => {
        const url = `https://github.com/itsFide/converter/blob/master/img/${n}.png?raw=true`;
        return [
          [ n,               url ],
          [ n.toUpperCase(), url ],
        ];
      }
    ));
    Ответ написан
    1 комментарий
  • Как на js преобразовать обьектный массив url дерева сайта в массив возможных url путей?

    0xD34F
    @0xD34F Куратор тега JavaScript
    function getPaths(obj, path = [ '' ]) {
      const entries = Object.entries(obj);
      return entries.length
        ? entries.reduce((acc, n) => (
            path.push(n[0]),
            acc.push(...getPaths(n[1], path)),
            path.pop(),
            acc
          ), [])
        : [ path.join('/') ];
    }
    Ответ написан
    4 комментария
  • Как написать скрипт сокращения цифр?

    0xD34F
    @0xD34F Куратор тега JavaScript
    function shortNumber(val) {
      const abs = Math.abs(val);
      const prefixIndex = Math.log10(abs) / 3 | 0;
      return (
        (val < 0 ? '-' : '') +
        Math.round(abs / (10 ** (prefixIndex * 3))) +
        'KMGTPEZY'.charAt(~-prefixIndex)
      );
    }

    shortNumber(99)       // '99'
    shortNumber(1945)     // '2K'
    shortNumber(-5839465) // '-6M'
    shortNumber(7e10)     // '70G'
    Ответ написан
    Комментировать
  • Почему не работает alert?

    0xD34F
    @0xD34F Куратор тега JavaScript
    Открываем консоль, читаем:

    A different origin subframe tried to create a JavaScript dialog. This is no longer allowed and was blocked.

    Вот так.
    Ответ написан
    1 комментарий
  • Как сделать функцию, которая меняет регистр всех ключей объекта?

    0xD34F
    @0xD34F Куратор тега JavaScript
    const replaceKeys = (val, replacer) =>
      val instanceof Array
        ? val.map(n => replaceKeys(n, replacer))
        : val instanceof Object
          ? Object.fromEntries(Object
              .entries(val)
              .map(n => [ replacer(n[0]), replaceKeys(n[1], replacer) ])
            )
          : val;
    
    const newObj = replaceKeys(obj, k => k.toUpperCase());
    Ответ написан
    Комментировать
  • Как добавить элементам текст из массива?

    0xD34F
    @0xD34F Куратор тега JavaScript
    Кому надо добавить текст:

    const elements = document.querySelectorAll('.descr');

    Как в элемент добавить текст:

    const addText = (el, index) =>
      el.append(arr[index]);
      // или
      // el.replaceChildren(arr[index]);
      // el.textContent = arr[index];
      // el.innerText = arr[index];
      // el.innerHTML = arr[index];
      // el.appendChild(document.createTextNode(arr[index]));
      // el.insertBefore(new Text(arr[index]), null);
      // el.insertAdjacentText('beforeend', arr[index]);
      // el.insertAdjacentHTML('beforeend', arr[index]);

    Добавляем:

    elements.forEach(addText);
    
    // или
    
    for (const [ i, n ] of elements.entries()) {
      addText(n, i);
    }
    
    // или
    
    for (let i = 0; i < elements.length; i++) {
      addText(elements[i], i);
    }
    
    // или
    
    (function next(i, n = elements.item(i)) {
      n && (addText(n, i), next(-~i));
    })(0);
    Ответ написан
    Комментировать
  • Самый гуманный способ удаления нескольких символов в начале строки?

    0xD34F
    @0xD34F Куратор тега JavaScript
    `${str | 0}`
    // или
    str.replace(/^0+/, '')
    // или
    str.match(/[^0].*/)[0]
    // или
    str.split(/^0*/).pop()
    // или
    str.slice(str.search(/[^0]/))
    // или
    [...str].reduce((acc, n) => (+n || acc) && acc + n, '')
    Ответ написан
    2 комментария
  • Js filter по найденным словам?

    0xD34F
    @0xD34F Куратор тега JavaScript
    $('#search-faq-input-filter').on('input', e => {
      const val = $(e.target).val().toLowerCase();
    
      $('.ia-item')
        .hide()
        .filter((i, n) => (
          $('.ia-content', n).text().toLowerCase().includes(val) ||
          $('.ia-title-link', n).text().toLowerCase().includes(val)
        ))
        .show();
    });
    Ответ написан
    1 комментарий
  • Как вытащить уникальные данные из массива объектов?

    0xD34F
    @0xD34F Куратор тега JavaScript
    В каком виде надо получить цвета? Если нужны строки (значения свойства name), то

    [...new Set(data.variations.map(n => n.color.name))]

    Если же нужны сами объекты, тогда

    Object.values(Object.fromEntries(data.variations.map(n => [ n.color.name, n.color ])))
    
    // или
    
    Object.values(data.variations.reduce((acc, { color: n }) => (acc[n.name] ??= n, acc), {}))
    
    // или
    
    data.variations.map(n => n.color).filter(function(n) {
      return !(this[n.name] = this.hasOwnProperty(n.name));
    }, {})

    Можно решить задачу и в более общем виде - сделаем функцию, параметрами которой будут итерируемый объект (помимо массивов можно будет уникализировать строки, NodeList'ы и т.п.) и функция, принимающая его элемент и возвращающая значение, по которому осуществляется уникализация:

    function unique(data, key = n => n) {
      const getKey = key instanceof Function ? key : n => n[key];
      const keys = new Set;
      const result = [];
    
      for (const n of data) {
        const k = getKey(n);
        !keys.has(k) && keys.add(k) && result.push(n);
      }
    
      return result;
    }

    // получаем массив уникальных имён цветов
    const uniqueStrColors = unique(data.variations.map(n => n.color.name));
    
    // получаем массив объектов цветов, свойства name которых уникальны
    const uniqueObjColors = unique(data.variations.map(n => n.color), n => n.name);
    Ответ написан
    1 комментарий
  • Как обернуть каждый элемент в ссылку с помощью JS?

    0xD34F
    @0xD34F Куратор тега JavaScript
    Кого и во что надо обернуть:

    const elements = document.querySelectorAll('.slider__itm img');
    const tag = 'a';

    Оборачиваем:

    elements.forEach(n => {
      n.after(document.createElement(tag));
      n.nextSibling.append(n);
    });

    или

    for (const n of elements) {
      const wrapper = document.createElement(tag);
      wrapper.appendChild(n.parentNode.replaceChild(wrapper, n));
    }

    или

    for (let i = 0; i < elements.length; i++) {
      const wrapper = document.createElement(tag);
      elements[i].replaceWith(wrapper);
      wrapper.insertAdjacentElement('afterbegin', elements[i]);
    }

    или

    (function next(i, n = elements.item(i)) {
      n && (n.outerHTML = `<${tag}>${n.outerHTML}</${tag}>`, next(-~i));
    })(0);
    Ответ написан
    3 комментария
  • Как отсортировать сегменты маршрута в порядке их прохождения?

    0xD34F
    @0xD34F Куратор тега JavaScript
    Собираем начальные и конечные точки сегментов маршрута (объекты вида { точка: сегмент }). Находим начальный сегмент маршрута - такой, начальная точка которого не является ничьей конечной. Следующий сегмент маршрута - такой, начальная точка которого является конечной точкой текущего сегмента. Ну и крутим цикл до тех пор, пока текущий сегмент маршрута существует, не забывая сохранять его в результирующий массив:

    function sort(route) {
      const pointsFrom = Object.fromEntries(route.map(n => [ n.from, n ]));
      const pointsTo = Object.fromEntries(route.map(n => [ n.to, n ]));
      const sorted = [];
    
      for (
        let segment = route.find(n => !pointsTo[n.from]);
        segment;
        segment = pointsFrom[segment.to]
      ) {
        sorted.push(segment);
      }
    
      return sorted;
    }
    Ответ написан
    Комментировать
  • Как удалить год из html разметки через JS?

    0xD34F
    @0xD34F Куратор тега JavaScript
    const remove = str => str.split(' ').slice(0, -1).join(' ');
    // или
    const remove = str => str.replace(/\s\S+$/, '');
    // или
    const remove = str => str.match(/.+(?=\s)/);
    // или
    const remove = str => str.slice(0, str.lastIndexOf(' '));

    for (const n of document.getElementsByClassName('startdate')) {
      n.textContent = remove(n.textContent);
    }
    
    // или, раз уж полной даты уже не будет, пусть начало и конец интервала дат
    // располагаются внутри одного элемента - вместе с куском строки также
    // удаляем и родительский элемент
    
    document.querySelectorAll('.startdate').forEach(n => {
      n.outerHTML = remove(n.innerHTML);
      // или
      n.replaceWith(remove(n.innerText));
    });
    Ответ написан
    Комментировать