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

    0xD34F
    @0xD34F Куратор тега JavaScript
    out.textContent = badWords.reduce(
      (str, n) => str.replaceAll(n, '*'.repeat(n.length)),
      field
    );

    или

    for (const n of badWords) {
      field = field.replace(RegExp(n, 'g'), Array(n.length + 1).join('*'));
    }
    
    out.innerText = field;

    или

    out.innerHTML = (function replace(str, i, n = badWords[i]) {
      return n
        ? replace(str.split(n).join(Array(n.length).fill`*`.join``), -~i)
        : str;
    })(field, 0);

    или

    out.replaceChildren(field.replace(
      RegExp(badWords.join('|'), 'g'),
      m => m.replaceAll(/./g, '*')
    ));
    Ответ написан
    Комментировать
  • Как перемножить два списка?

    0xD34F
    @0xD34F
    [ n2 / n1 * 1000 for n1, n2 in zip(list1, list2) ]
    # или
    [ list2[i] / n * 1000 for i, n in enumerate(list1) ]
    # или
    [ list2[i] / list1[i] * 1000 for i in range(len(list1)) ]
    Ответ написан
    Комментировать
  • Как показать/спрятать блок каждые 5 сек и одновременно менять информацию в блоке?

    0xD34F
    @0xD34F Куратор тега JavaScript
    let index = -1;
    
    setInterval(el => {
      const show = !el.classList.contains('_active');
      index = (index + show) % infoModal.length;
      el.innerText = infoModal[index].title;
      el.classList.toggle('_active', show);
    }, 1000, document.querySelector('.modal__title'));

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

    Если, к примеру, нужно скрывать блок каждый раз через5 сек, а показывать блок через рандомный промежуток времени?

    К чёрту setInterval, делаете функцию, которая вызывает себя по таймауту - случайному при скрытии элемента и фиксированному при показе:

    (function updateText(el, i) {
      const show = el.classList.toggle('_active');
      i = (i + show) % infoModal.length;
      el.textContent = infoModal[i].title;
      setTimeout(updateText, 1000 + !show * Math.random() * 3000, el, i);
    })(document.querySelector('.modal__title'), -1);
    Ответ написан
    3 комментария
  • Почему не задается время прогресс-бару?

    0xD34F
    @0xD34F Куратор тега CSS
    Время, которое я задаю, применяется к fadeOut, а вот к runProgress нет

    Окей, посмотрим на эти fadeOut и runProgress:

    this.fadeOut = `fadeOut ${this.time}s linear forwards`,
    this.runProgress = `runProgress ${this.time}s liner forwards`,

    Вам вопрос: чем отличаются эти две строки (конечно, помимо имён анимаций)?

    UPD. А это вообще нормально - всем назначать одно и то же значение? В смысле, в шаблоне эти fadeOut и runProgress используются для задания анимации элементам, у которых есть предок с v-for. Если изменить значение свойства time и добавить в messages новый элемент, то у тех, что были добавлены раньше, изменится длительность анимации. Наверное, стоит вырезать свойства fadeOut и runProgress, элементам messages при создании добавлять актуальное значение свойства time, типа time: this.time, и использовать его при задании стилей:

    methods: {
      getStyle: (name, { time }) => ({
        animation: `${name} ${time}s linear forwards`,
      }),
      ...

    :style="getStyle('fadeOut', message)"

    :style="getStyle('runProgress', message)"
    Ответ написан
    1 комментарий
  • Как реализовать отображение компонентов из массива?

    0xD34F
    @0xD34F Куратор тега React
    сделал две функции, которые поочерёдно возвращают компонент согласно индексу

    Возвращают куда? Что с возвращённым происходит? Да ничего.

    желаемого эффекта не получил

    А как родительский компонент узнает, что при изменении индекса надо выполнить рендеринг? Да никак.

    в консоль выводиться...

    Не понимаю, зачем вы это сказали. Никакого кода с выводом в консоль показано не было.

    Исправляем: в массив складываем сами компоненты вместо их экземпляров; индекс делаем состоянием; по клику на кнопки обновляем индекс; используя индекс извлекаем из массива компонент. Всё:

    const Component1 = () => <h1>hello, world!!</h1>;
    const Component2 = () => <h1>fuck the world</h1>;
    const Component3 = () => <h1>fuck everything</h1>;
    
    const components = [ Component1, Component2, Component3 ];
    
    function App() {
      const [ index, setIndex ] = useState(0);
      const min = 0;
      const max = components.length - 1;
    
      const Component = components[index];
    
      const onClick = ({ target: { dataset: { step } } }) =>
        setIndex(Math.max(min, Math.min(max, index + +step)));
    
      return (
        <div>
          <button onClick={onClick} data-step="-1" disabled={index <= min}>prev</button>
          <button onClick={onClick} data-step="+1" disabled={index >= max}>next</button>
          {Component && <Component />}
        </div>
      );
    }
    Ответ написан
    Комментировать
  • Как провалидировать форму в которой несколько инпутов и селектов?

    0xD34F
    @0xD34F Куратор тега JavaScript
    document.querySelector('form').addEventListener('input', e => {
      document.querySelector('button').disabled = ![
        [  'input', el => el.value         ],
        [ 'select', el => el.selectedIndex ],
      ].every(([ selector, validator ]) => {
        return [...e.currentTarget.querySelectorAll(selector)].every(validator);
      });
    });
    Ответ написан
    2 комментария
  • Почему при глубоком копировании объектов переполняется стек вызовов?

    0xD34F
    @0xD34F Куратор тега JavaScript
    const entries = Object.entries(obj);
    for (const entry of entries) {
      if (!isObject(entry)) {
        result = Object.assign(result, Object.fromEntries(entry));
      } else return cloneDeep(entry);

    Что такое entries? - массив, состоящий из массивов.
    Чем, соответственно, является entry? - массивом.
    Что возвращает isObject для массивов? - true.
    То есть, вне зависимости от содержимого конкретного entry произойдёт рекурсивный вызов.
    Всё.
    Ответ написан
    1 комментарий
  • Как поменять надпись на кнопке через 4 секунды?

    0xD34F
    @0xD34F Куратор тега React
    const [ buttonText, setButtonText ] = useState('hello, world!!');
    const [ clicked, setClicked ] = useState(false);
    
    function onClick() {
      setClicked(true);
      setTimeout(() => {
        setButtonText('fuck the world');
        setClicked(false);
      }, 1000);
    }

    <button onClick={onClick} disabled={clicked}>{buttonText}</button>
    {clicked ? <img src="..." /> : null}
    Ответ написан
    2 комментария
  • Как произвести слияние массива объектов с другим массивом объектов?

    0xD34F
    @0xD34F Куратор тега JavaScript
    Массивы складываем в массив: const arrs = [ arr1, arr2 ];.

    Дальше можно сделать просто:

    const result = arrs.reduce((acc, n) => (
      n.forEach((m, i) => Object.assign(acc[i] ??= {}, m)),
      acc
    ), []);

    Или сложно:

    function* zip(data, defaultValue = null) {
      const iterators = Array.from(data, n => n[Symbol.iterator]());
    
      for (let doneAll = false; doneAll = !doneAll;) {
        const values = [];
    
        for (const n of iterators) {
          const { value, done } = n.next();
          values.push(done ? defaultValue : value);
          doneAll &&= done;
        }
    
        if (!doneAll) {
          yield values;
        }
      }
    }
    
    const result = Array.from(zip(arrs), n => Object.assign({}, ...n));
    Ответ написан
    1 комментарий
  • Как заменить все цифры на странице?

    0xD34F
    @0xD34F Куратор тега JavaScript
    Какие есть косяки:
    • Перебираете вложенные узлы, но замену выполняете у того, что передан в функцию.
    • Заменять содержимое надо только у текстовых узлов - чтобы проверить тип, смотрим nodeType.
    • У текстовых узлов нет innerText. Есть textContent и nodeValue.
    • Зачем функции знать заранее, что за замена должна быть выполнена? Что будете делать, если понадобится выполнить другую замену - закопипастите функцию, заменив регулярку? Лучше добавим второй параметр - функцию, принимающую текущий текст и возвращающую новый.

    Исправляем:

    function replaceText(node, replacer) {
      if (node.nodeType === Node.ELEMENT_NODE) {
        node.childNodes.forEach(n => replaceText(n, replacer));
      } else if (node.nodeType === Node.TEXT_NODE) {
        node.textContent = replacer(node.textContent);
      }
    }

    Или, долой рекурсию и проверки типов узлов, можно сразу текстовые перебирать:

    function replaceText(node, replacer) {
      const iter = document.createNodeIterator(node, NodeFilter.SHOW_TEXT);
    
      for (let n = null; n = iter.nextNode();) {
        n.nodeValue = replacer(n.nodeValue);
      }
    }

    Пример использования:

    replaceText(document.body, str => str.replace(/\d/g, 'hello, world!!'));
    Ответ написан
    Комментировать
  • Как изменить порядок вызова обработчиков событий?

    0xD34F
    @0xD34F Куратор тега React
    Смотрим, что умеет addEventListener:

    useCapture

    A boolean value indicating whether events of this type will be dispatched to the registered listener before being dispatched to any EventTarget beneath it in the DOM tree.

    Соответственно, element.addEventListener(event, handler, true).
    Ответ написан
    Комментировать
  • Как при повторном добавлении товара в корзину вместо дублирования увеличивать его количество?

    0xD34F
    @0xD34F
    case ADD_PRODUCT:
      const item = state.products.find(n => n.id === action.payload.id);
      return {
        ...state,
        products: item
          ? state.products.map(n => n === item ? { ...n, count: n.count + 1 } : n)
          : [ ...state.products, { ...action.payload, count: 1 } ],
      };
    Ответ написан
    1 комментарий
  • Как сделать, что бы считало все три категории?

    0xD34F
    @0xD34F Куратор тега JavaScript
    document.querySelector('.ticket_content').addEventListener('input', e => {
      document.querySelector('.ticket_price').innerText =
        Array.prototype.reduce.call(
          e.currentTarget.querySelectorAll('.plus_minus'),
          (acc, n) => acc + n.querySelector('input').value * n.nextElementSibling.innerText,
          0
        );
    });
    Ответ написан
  • Как правильно рекурсивно обойти словарь?

    0xD34F
    @0xD34F
    def get_keys(arr):
      return sum((get_keys(sub) if len(sub := n['subCategories']) else [ n['key'] ] for n in arr), [])
    Ответ написан
    Комментировать
  • Как пронумеровать элементы?

    0xD34F
    @0xD34F Куратор тега JavaScript
    Где элементы находятся, как назначать им текст в зависимости от индекса контейнера:

    const containers = document.querySelectorAll('.item');
    const setTexts = (container, index) => container
      .querySelectorAll('.card-item')
      .forEach(n => n.textContent = `button ${-~index}`);

    Назначаем:

    // индекс передаётся в коллбек forEach'а
    containers.forEach(setTexts);
    
    // или, индекс отдаёт итератор entries
    for (const [ i, n ] of containers.entries()) {
      setTexts(n, i);
    }
    
    // или, можно самостоятельно обновлять значение переменной с индексом
    for (let i = 0; i < containers.length; i++) {
      setTexts(containers[i], i);
    }
    
    // и цикл для этого использовать не обязательно
    (function next(i, n = containers.item(i)) {
      n && (setTexts(n, i), next(i + 1));
    })(0);
    Ответ написан
    1 комментарий
  • Как выводить варианты ответов в случайном порядке?

    0xD34F
    @0xD34F Куратор тега Vue.js
    function shuffle(arr) {
      for (let i = arr.length; i > 1;) {
        const j = Math.random() * (i--) | 0;
        [ arr[i], arr[j] ] = [ arr[j], arr[i] ];
      }
    
      return arr;
    }

    computed: {
      shuffledAnswers() {
        return shuffle(Object.entries(this.questions[this.idx].answers));
      },
      ...

    <div v-for="[ key, answer ] in shuffledAnswers">
      ...

    UPD. Конечно, вопрос был не об этом, но есть ряд замечаний по поводу показанного кода.

    "answers": {

    Пусть это будет массив. Соответственно, правильный ответ будет обозначаться через индекс.

    import usersData from "../questions.json";

    Не надо импортировать вопросы в компоненте теста, пусть они передаются в него через props.

    selectedAnswer: "",

    Всего один? Этого мало, надо запоминать все полученные ответы.

    count: 5,

    <div v-if="idx < count">

    Если завтра добавятся новые вопросы или удалятся какие-то из существующих, побежите изменять значение этого свойства? Оно не нужно, надо смотреть на длину массива с вопросами. Или, можно сделать вычисляемое свойство, представляющее текущий вопрос (просто извлекаем элемент из массива с вопросами по индексу текущего вопроса), и проверять, существует ли он.

    computed:{
      randomQuestions () {
        usersData.sort(() => Math.random() - 0.5)

    Во-первых, вычисляемые свойства не должны изменять данные. Во-вторых, почему не надо так сортировать. Поскольку массив вопросов никак не изменяется, делать тут вычисляемое свойство смысла нет, пусть оно будет обычным. Перемешанная копия массива с вопросами, у вопросов перемешанные массивы ответов, а также добавлено свойство под ответ, выбранный пользователем.

    :disabled="selectedAnswer != ''"

    Блокировать выбор ответа не надо - вдруг пользователь случайно не туда нажал. Пусть будет возможность изменить сделанный выбор. Это касается не только ответов на текущий вопрос, а всех, т.е., в дополнение к

    <button
      @click="nextQuestion"

    надо сделать такую же кнопку для перехода к предыдущему вопросу.

    document.querySelectorAll("input").forEach((el) => (el.checked = false));

    Не надо лезть в DOM руками. Чтобы при переходе к следующему вопросу сбрасывать выбор, достаточно пересоздавать элементы, назначив их общему предку ключ, зависящий от индекса (:key="индекс_вопроса"). Но это, конечно, костыльное решение. Правильно будет управлять радиокнопками основываясь на данных, через v-model.

    @change="answered($event)"

    answered(e) {
      this.selectedAnswer = e.target.value;
      if (this.selectedAnswer == this.questions[this.idx].correctAnswer) {
        this.correctAnswers++;

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

    https://jsfiddle.net/0L9ayx1u/1/
    Ответ написан
    1 комментарий
  • Почему не могу перейти к странице по прямому адресу?

    0xD34F
    @0xD34F Куратор тега Vue.js
    Потому что документацию не читаете:

    поскольку наше приложение — одностраничное, не сконфигурировав соответствующим образом сервер мы заставим пользователей получать ошибку 404, если они перейдут по http://oursite.com/user/id напрямую

    <...>

    всё, что нужно — единственная "резервная" запись в конфигурации сервера. Если URL не совпадает ни с одним статическим файлом, сервер должен просто отдать index.html, в котором и живёт наше приложение
    Ответ написан
    Комментировать
  • Как код переписать?

    0xD34F
    @0xD34F Куратор тега JavaScript
    const bullshitInsert = str => str
      .replace(/(?<=[2468])(?=[2468])/g, '*')
      .replace(/(?<=[13579])(?=[13579])/g, '-');

    или

    const bullshitInsert = str => Array
      .from(str, (n, i) => (n * str[i - 1] && !((n ^ str[i - 1]) & 1) ? '*-'[n & 1] : '') + n)
      .join('');
    Ответ написан
    3 комментария
  • Как объединить массив с повторяющимися объектами?

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

    const result = Object
      .entries(arr.reduce((acc, n) => ((acc[n.name] ??= []).push(n.value), acc), {}))
      .reduce((acc, [ k, v ]) => (acc[k] = v.length === 1 || v, acc), {});

    Но почему

    ThirdName: true

    ??

    В самом деле так и надо, или всё-таки там должна быть строка с датой из исходного массива? А что если значения повторяются? Вот вариант с получением только уникальных значений и без дурацкого true там, где значение одно:

    const result = Object
      .entries(arr.reduce((acc, n) => ((acc[n.name] ??= new Set).add(n.value), acc), {}))
      .reduce((acc, [ k, [...v] ]) => (acc[k] = ~-v.length ? v : v[0], acc), {});
    Ответ написан
    2 комментария