Задать вопрос
  • Можно ли через регулярные выражения вставить в текст символ?

    0xD34F
    @0xD34F Куратор тега JavaScript
    Регулярные выражения не нужны:

    const insert = (str, substr, ...indices) => [ 0 ]
      .concat(indices)
      .filter(n => 0 <= n && n <= str.length)
      .sort((a, b) => a - b)
      .map((n, i, a) => str.slice(n, a[i + 1]))
      .join(substr);
    
    // или
    
    const insert = (str, substr, ...indices) => indices
      .sort((a, b) => b - a)
      .reduce((acc, n) => (
        0 <= n && n <= str.length && acc.splice(n, 0, substr),
        acc
      ), [...str])
      .join('');
    
    // или
    
    const insert = (str, substr, ...indices) =>
      ''.concat(...Array.from(
        { length: -~str.length },
        function(_, i) {
          return substr.repeat(this[i] ?? 0) + str.charAt(i);
        },
        indices.reduce((acc, n) => (acc[n] = -~acc[n], acc), {})
      ));

    Но, конечно, можно и с ними:

    const insert = (str, substr, ...indices) => indices
      .filter(n => 0 <= n && n <= str.length)
      .sort((a, b) => a - b)
      .reduceRight((acc, n, i) =>
        acc.replace(RegExp(`(?<=^.{${n}})`), substr)
      , str);

    Как использовать:

    // ваш случай
    const str = insert(`${number}`, '-', 3, 5, 8, 10);
    
    // вставлять можно больше одного символа
    insert('abc', ' --> ', 1, 2) // 'a --> b --> c'
    
    // можно по одному индексу несколько раз делать вставку
    insert('abc', '~', 0, 0, 0) // '~~~abc'
    
    // за границы строки вставка не выполняется,
    // за исключением позиции сразу же после конца строки
    insert('abc', '!', -1, 3, 4) // 'abc!'
    Ответ написан
    Комментировать
  • Как заставить работать несколько граф с оценками?

    0xD34F
    @0xD34F Куратор тега JavaScript
    вторая не работает

    Работает. Только не независимо, а как часть первой. Надо не все .grade-item обрабатывать, а только те, у кого в предках тот же .grade-item-block, что и у кликнутого.

    const container = document.querySelector('.nav-student-new-lesson');
    const blockSelector = '.grade-item-block';
    const itemSelector = `${blockSelector} .grade-item`;
    const colors = {
      grades: [
        [ 5, 'rgba(150, 255, 0, 0.3)' ],
        [ 3, 'rgba(255, 150, 0, 0.3)' ],
        [ 1, 'rgba(255,   0, 0, 0.3)' ],
      ],
      default: 'white',
    };
    
    function updateGrade(item) {
      const items = item.closest(blockSelector).querySelectorAll(itemSelector);
      const grade = 1 + Array.prototype.indexOf.call(items, item);
      const color = colors.grades.find(n => n[0] <= grade)[1];
      items.forEach((n, i) => n.style.background = i < grade ? color : colors.default);
    }

    Можно сделать делегированный обработчик:

    container.addEventListener('click', ({ target: t }) =>
      (t = t.closest(itemSelector)) && updateGrade(t)
    );

    Или слушать клики непосредственно на .grade-item:

    container.querySelectorAll(itemSelector).forEach(function(n) {
      n.addEventListener('click', this);
    }, e => updateGrade(e.currentTarget));
    Ответ написан
    Комментировать
  • Как сгенерировать список по многим условиям?

    0xD34F
    @0xD34F
    function generator($str, $params) {
      $result = [];
    
      if (count($params)) {
        $key = key($params);
        $values = is_array($params[$key]) ? $params[$key] : [ $params[$key] ];
        unset($params[$key]);
    
        foreach ($values as $val) {
          array_push($result, ...generator(str_replace("{{$key}}", $val, $str), $params));
        }
      } else {
        $result[] = $str;
      }
    
      return $result;
    }
    Ответ написан
    5 комментариев
  • Как переключить подсветку на следующий элемент списка при нажатии стрелок вверх-вниз?

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

    const container = document.querySelector('#list');
    const activeClass = 'active';

    Переключаем:

    container.firstElementChild.classList.add(activeClass);
    
    document.addEventListener('keydown', e => {
      const nextElKey = ({
        ArrowDown: 0,
        ArrowUp: 1,
      })[e.key];
    
      const currEl = container.querySelector(`:scope > .${activeClass}`);
      const nextEl =
        currEl[[ 'nextElementSibling', 'previousElementSibling' ][nextElKey]]/* ??
        container[[ 'firstElementChild', 'lastElementChild' ][nextElKey]]*/;
    
      // если надо, чтобы при переходе от последнего к следующему элементу
      // активным становился первый, а при переходе от первого к предыдущему
      // активным становился последний, достаточно удалить многострочное 
      // комментирование выше
    
      if (nextEl) {
        currEl.classList.remove(activeClass);
        nextEl.classList.add(activeClass);
      }
    });

    или

    const next = function(step) {
      this[1][this[0]].classList.remove(activeClass);
    
      this[0] = Math.max(0, Math.min(this[1].length - 1, this[0] + step));
      // или, если надо, чтобы выделение по кругу бегало
      // this[0] = (this[0] + step + this[1].length) % this[1].length;
    
      this[1][this[0]].classList.add(activeClass);
    }.bind([ 0, container.children ]);
    
    next(0);
    
    document.addEventListener('keydown', ({ key }) => {
      const step = +(key === 'ArrowDown') || -(key === 'ArrowUp');
      if (step) {
        next(step);
      }
    });
    Ответ написан
    Комментировать
  • Как добавить точку на карте yandex map в Vue 3?

    0xD34F
    @0xD34F Куратор тега Яндекс.Карты
    думаю что тут проблема из за proxy

    Тогда попробуйте получать оригинальный объект и работать уже с ним:

    Vue.toRaw(this.map).geoObjects.add(placemark);

    Или изначально не делайте его реактивным:

    this.map = Vue.markRaw(new ymaps.Map(this.$refs.map, {
      ...
    Ответ написан
    1 комментарий
  • Как сделать смену картинок, если кликнули в вертикальном слайдере?

    0xD34F
    @0xD34F
    card_gallery.on('click', function(swiper, e) {
      const index = swiper.slides.indexOf(e.target.closest('.swiper-slide'));
      if (index !== -1) {
        single_gallery.slideTo(index);
      }
    });

    Или попробуйте добавить slideToClickedSlide: true в настройки card_gallery.
    Ответ написан
    1 комментарий
  • Как вернуть новый массив объектов только с уникальным id вложенного объекта?

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

    Object.values(Object.fromEntries(arr.map(n => [ n.user.id, n ])))
    
    // или, если в результирующий массив должны попадать те из "одинаковых" элементов,
    // что расположены в исходном массиве первыми
    
    Object.values(arr.reduce((acc, n) => (acc[n.user.id] ??= n, acc), {}))
    
    // или, если также надо сохранять взаимное расположение элементов
    
    arr.filter(function({ user: { id: n } }) {
      return !(this[n] = this.hasOwnProperty(n));
    }, {})

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

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

    Теперь можно делать так (ваш случай): const result = [...unique(arr, n => n.user.id)];.

    Или так:

    Array.from(unique([{id: 1}, {id: 2}, {id: 1}, {id: 1} ], 'id')) // [{id: 1}, {id: 2}]

    Или так: ''.concat(...unique('ABBACACCCBA')) // 'ABC'.

    Или так:

    for (const n of unique(Array(20).keys(), n => Math.sqrt(n) | 0)) {
      console.log(n); // 0 1 4 9 16
    }
    Ответ написан
    Комментировать
  • Почему не срабатывает transition-group в vue?

    0xD34F
    @0xD34F Куратор тега Vue.js
    Vue DevTools говорит, что используемая версия - 2.6.14. В то время как класс, отвечающий за анимацию появления, соответствует третьей версии (читаем документацию):

    .list-enter-from {

    Кроме того, если хотите, чтобы анимация отрабатывала при первом рендеринге, для transition-group следует добавить параметр appear.
    Ответ написан
    3 комментария
  • Почему нет данных, полученных через fetch (React)?

    0xD34F
    @0xD34F Куратор тега React
    Вопрос бессмысленный, данные есть.

    fetch('https://jsonplaceholder.typicode.com/todos/1')

    Указывая id, вы получаете один объект. Объект, а не массив. Уберите 1.

    const [data, setData] = useState(null);

    {data.map(item => (

    Бывает ли у null метод map? - погуглите, разберитесь. Ну и замените null на [].
    Ответ написан
    Комментировать
  • Как активировать select по нажатию на radio?

    0xD34F
    @0xD34F Куратор тега JavaScript
    const radios = document.querySelectorAll('[name="radios"]');
    const selects = Array.from(radios, n => n.nextElementSibling);
    const onChange = e => selects.forEach(n => n.disabled = n !== e.target.nextElementSibling);
    radios.forEach(n => n.addEventListener('change', onChange));
    Ответ написан
  • Как сделать итерацию по вложенному хешу?

    0xD34F
    @0xD34F
    data.each_value{|n|
      puts("#{n[:name]}: вес #{n[:weight]} г., количество #{n[:qty]} шт.")
    }
    Ответ написан
    1 комментарий
  • Как создать массив чисел, которые увеличиваются с каждой итерацией?

    0xD34F
    @0xD34F Куратор тега JavaScript
    const arithmeticProgression = ({ length, a1 = 0, d = 1 }) =>
      Array.from(
        { length },
        (n, i) => a1 + i * d
      );

    const arr = arithmeticProgression({
      length: 10,
      a1: 6,
      d: 3,
    });

    или

    function* arithmeticProgression(a1, d, length) {
      for (let i = 0; i < length; i++) {
        yield a1 + i * d;
      }
    }

    for (const n of arithmeticProgression(100, 10, 5)) {
      console.log(n);
    }
    
    console.log(Array.from(arithmeticProgression(10, -7, 10)));
    Ответ написан
    Комментировать
  • Как написать фильтр для вывода в консоль исходя из передаваемого аргумента?

    0xD34F
    @0xD34F
    def fucking_filter(arr, max_count, key=lambda n: n):
      filtered = []
      count = {}
    
      for n in arr:
        k = key(n)
        count[k] = count.get(k, 0) + 1
        if count[k] <= max_count:
          filtered.append(n)
    
      return filtered
    
    
    for n in fucking_filter(genres, N):
      print(n)
    Ответ написан
    2 комментария
  • Debounce и динамический input v-model как подружить?

    0xD34F
    @0xD34F Куратор тега Vue.js
    хочу сделать задержку ввода

    Ну так и следите тогда за вводом:

    methods: {
      onInput: debounce(function(val) {
        this.debouncedInput = val;
      }, 500),
      ...

    <v-text-field
      @input="onInput"
      ...

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

    computed: {
      count() {
        return this.orders.map(n => n.count);
      },
    },
    watch: {
      count: debounce(function(newVal, oldVal) {
        this.debouncedInput = newVal.find((n, i) => n !== oldVal[i]);
      }, 500),
    },
    Ответ написан
    Комментировать
  • Возможно ли добавить .active к маркеру с помощью router-link?

    0xD34F
    @0xD34F Куратор тега Vue.js
    data: () => ({
      links: [ 'tasks', 'kanban', 'activity', 'calendar', 'files' ],
    }),

    ul
      li(v-for="n in links")
        router-link(:to="{ name: n }") {{ n }}
    .marker
      div(v-for="n in links" :class="[ `select${n}`, $route.name === n ? 'active' : '' ]")
        span

    https://jsfiddle.net/rmnLokj3/

    Непонятно только зачем оно надо - убрали бы эти "маркеры", и стилизовали сами ссылки, там вручную никаких классов добавлять не надо, уже всё есть.

    https://jsfiddle.net/rmnLokj3/1/
    Ответ написан
    Комментировать
  • Почему в параметр функции компонента Vue 3 прилетает undefined?

    0xD34F
    @0xD34F Куратор тега Vue.js
    const certificate = ref({});

    shortingTechItems(certificate.pto)

    прилетает undefined

    Вот это на хрен неожиданность - пытаемся прочитать из объекта значение несуществующего свойства и получаем... получаем... А-а-а-а-а-а!!!!!!111

    В чем проблема

    В нулевых знаниях js.

    как исправить?

    Вообще - освоить js.

    Ну а прямо сейчас можете задать для передаваемого в функцию свойства дефолтное значение в виде пустого массива. Или можете проверять внутри функции, что пришло, если не массив - не пытаться пользоваться этой штукой как массивом. Или можете не рендерить элемент, по данных нет.

    UPD. Обязательно тратить семь строк на то, что можно сделать в одну?

    - const shortingTechItems = (item) => {
    -   const arr = [];
    -   item.map((i) => {
    -     arr.push(Number(i.replace(/\D+/g, "")));
    -   });
    -   return arr;
    - };
    + const shortingTechItems = items => items.map(n => +n.replace(/\D/g, ''));
    Ответ написан
    Комментировать
  • Как сделать компонент радио-кнопок на Vue?

    0xD34F
    @0xD34F Куратор тега Vue.js
    Vue 2, options API
    Компонент радиогруппы:

    props: [ 'value' ],
    provide() {
      return {
        radioGroup: this,
      };
    },

    Компонент радиокнопки:

    props: [ 'value' ],
    inject: [ 'radioGroup' ],

    <input
      type="radio"
      :value="value"
      :checked="radioGroup.value === value"
      @change="radioGroup.$emit('input', value)"
    >

    https://jsfiddle.net/d7aow8fq/

    Vue 3, composition API
    Компонент радиогруппы:

    props: [ 'modelValue' ],
    emits: [ 'update:modelValue' ],
    setup(props, { emit }) {
      provide('radioGroupValue', computed({
        get: () => props.modelValue,
        set: v => emit('update:modelValue', v),
      }));
    },

    Компонент радиокнопки:

    props: [ 'value' ],
    setup() {
      return {
        radioGroupValue: inject('radioGroupValue'),
      };
    },

    <input
      type="radio"
      :value="value"
      v-model="radioGroupValue"
    >

    https://jsfiddle.net/d7aow8fq/2/
    Ответ написан
    4 комментария
  • Как сделать object to HTML string?

    0xD34F
    @0xD34F Куратор тега JavaScript
    const voidTags = [ 'input', 'img', 'br', 'hr', ещё какой-то тэг, и ещё, ... ];
    
    function createHTML(data) {
      const attrs = Object
        .entries(data.attrs ?? {})
        .map(n => `${n[0]}="${n[1]}"`)
        .join(' ');
    
      const startTag = `<${data.tagName}${attrs && (' ' + attrs)}>`;
    
      if (voidTags.includes(data.tagName)) {
        return startTag;
      }
    
      const children = (data.subTags ?? [])
        .map(createHTML)
        .join('');
    
      return `${startTag}${data.text ?? ''}${children}</${data.tagName}>`;
    }
    Ответ написан
    Комментировать
  • Как вернуть нужное значение?

    0xD34F
    @0xD34F
    def sq(n):
      return '\n'.join('x' * (i + 1) for i in range(n))
    Ответ написан