Задать вопрос
  • Реактивность не совсем работает vue 3?

    0xD34F
    @0xD34F Куратор тега Vue.js
    Открываем раздел документации, посвящённый реактивности, и читаем там, что

    Отследить переназначение локальных переменных <...> не получится, такого механизма просто нет в JavaScript. Можно лишь отслеживать изменения свойств объектов.

    Так что менять надо внутреннее содержимое, а не заменять объект на полностью новый. Вместо reactive следует использовать ref (соответственно, вместо copyDB = будет copyDB.value =), или же удалять существующие элементы массива, и добавлять новые:

    copyDB.splice(0, copyDB.length, ...addFlags(props.items));
    Ответ написан
    Комментировать
  • Как передать данные через vuex в router?

    0xD34F
    @0xD34F Куратор тега Vue.js
    не передаются данные в router-link

    А что за данные? Почему не показали (да и не только данные - ни строчки кода не вижу)? Случайно не объект запихнуть пытаетесь? - если так, то скорее всего всё передаётся, но данные превращаются в мусор. Дело в том, что роутер приводит значения параметров к строкам (кроме массивов - они-то останутся массивами, в строки будут превращены их элементы). Соответственно, если дальше вы из полученной строки или строк попытаетесь извлечь какие-то свойства (конечно из тех, что у строк нет), то получите undefined.

    Если же сделать корзину на одной странице с каталогом, то все прекрасно записывается в массив корзины.

    Что-то не понял, что конкретно вы пытаетесь сделать. Вижу два варианта, и оба бредовые.

    1. Вы пытаетесь добавлять товар в корзину при переходе по ссылке. Если так - не надо никуда переходить, вместо router-link сделайте кнопку, по клику на которую сразу будет вызываться соответствующее действие или мутация.

    2. Вы пытаетесь через router-link передать в компонент корзины массив добавленных в неё товаров. Если так - не надо ничего передавать, пусть компонент корзины забирает данные сразу из vuex.
    Ответ написан
  • В чем причина ошибки 'expected "*\\n"' to equal '"*"'?

    0xD34F
    @0xD34F Куратор тега JavaScript
    Ожидается '*' в качестве результата, реально вы выдаёте '*\n'.

    Лишний перенос строки в самом конце - тут лучше сделать массив, каждый элемент которого будет представлять отдельную строку результата, и склеить его в одну строку, типа .join('\n'). Ну и ещё пробелов не хватает после звёздочек.

    Исправлено.
    const christmasTree = length =>
      Array.from({ length }, (n, i) => (
        n = ' '.repeat(length - i - 1),
        n + '*'.repeat(i * 2 + 1) + n
      )).join('\n');
    Ответ написан
  • Как извлечь случайный элемент из вложенных массивов?

    0xD34F
    @0xD34F Куратор тега JavaScript
    Извлечение случайного элемента массива выносим в отдельную функцию:

    const random = arr => arr[Math.random() * arr.length | 0];

    Дальше можно получить случайный элемент случайного элемента:

    const item = random(random(Object.values(state.themes)));

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

    const item = random(Object.values(state.themes).flat());

    Какой из вариантов предпочесть? Зависит от того, как должны распределяться вероятности выпадения элементов - в случае, если выбирать элемент в два приёма, и размеры вложенных массивов различны, вероятности будут разными для разных массивов. Предположим, есть два вложенных массива, в одном два элемента, во втором сто. Получается, у элементов первого массива шанс быть выбранными один к четырём (один из двух массивов, один из двух элементов - 0.5 умножается на 0.5), а у элементов второго - один к двумстам (0.5 * 0.01).

    То есть, если должны быть равны вероятности выпадения элементов - объединяем вложенные массивы в один. Если равными должны быть вероятности принадлежности выбранного элемента к вложенным массивам, то выбираем сначала массив, а потом элемент внутри него.

    Но что если вероятности выпадения элементов должны быть равны, а размеры вложенных массивов велики, и не хотелось бы тратить на их объединение ни время, ни память? Возвращаемся к двум выборам, но выбирать вложенные массивы надо не с равными вероятностями, а учитывая их размеры:

    function weightedRandom(arr, key = () => 1) {
      const val = key instanceof Function ? key : n => n[key];
      const max = arr.reduce((acc, n) => acc + val(n), 0);
    
      return () => {
        let rand = Math.random() * max;
        return arr.find(n => (rand -= val(n)) < 0);
      };
    }

    const randomArr = weightedRandom(Object.values(state.themes), 'length');
    
    // ...
    
    const item = random(randomArr());
    Ответ написан
    Комментировать
  • Как сделать доп фильтр?

    0xD34F
    @0xD34F Куратор тега Vue.js
    <option v-for="item in info">
      {{ item.fieldTypes.geo }}
    </option>

    Это неправильно. Если значения в fieldTypes.geo не уникальны, option'ы тоже будут повторяться. Зачем это? Не надо. Делаем вычисляемое свойство, представляющее уникальные значение, и используем при создании option'ов его:

    computed: {
      uniqueGeo() {
        return [...new Set(this.info.map(n => n.fieldTypes.geo))];
      },
      ...

    <option v-for="n in uniqueGeo">{{ n }}</option>

    В вычисляемом свойстве, которое представляет отфильтрованные данные, добавляем проверку второго значения, переписываем его следующим образом:

    computed: {
      filteredOffers() {
        const vacancy = this.searchVacancyName.toUpperCase();
        const geo = this.searchGeo;
    
        return this.info.filter(n => (
          (!vacancy || n.fieldTypes.vacancyName.toUpperCase().includes(vacancy)) &&
          (!geo || n.fieldTypes.geo === geo)
        ));
      },
      ...
    Ответ написан
    1 комментарий
  • Как получить каждый последний подряд идущий элемент с нужным классом?

    0xD34F
    @0xD34F Куратор тега JavaScript
    const elements = Array.prototype.filter.call(
      document.querySelectorAll('.green'),
      (n, i, a) => n.nextElementSibling !== a[i + 1]
    );

    Если отдельно стоящие элементы не интересуют, то замените селектор на '.green + .green', или при фильтрации дополнительно проверяйте, что n.previousElementSibling === a[i - 1].
    Ответ написан
    1 комментарий
  • Как получить часть строки после последнего «/»?

    0xD34F
    @0xD34F Куратор тега JavaScript
    str.split('/').pop()
    // или
    str.match(/[^\/]+$/)[0]
    // или
    str.replace(/.*\//, '')
    // или
    str.slice(str.lastIndexOf('/') + 1)
    // или
    Array.from(str).reduce((acc, n) => n === '/' ? '' : acc + n, '')
    // или
    [...str].filter((n, i, a) => !a.includes('/', i)).join('')
    Ответ написан
    1 комментарий
  • Как отрисовать компонент CircleTopik только в среднем компоненте Card?

    0xD34F
    @0xD34F Куратор тега React
    function Card(props) {
      return (
        <div>
          {props.children}
        </div>
      );
    }
    
    function App() {
      return (
        <div>
          <Card />
          <Card>
            <CircleTopik />
          </Card>
          <Card />
        </div>
      );
    }

    или

    function Card({ showCircle }) {
      return (
        <div>
          {showCircle ? <CircleTopik /> : null}
        </div>
      );
    }
    
    function App() {
      return (
        <div>
          <Card />
          <Card showCircle />
          <Card />
        </div>
      );
    }
    Ответ написан
    Комментировать
  • Почему не вызывается второй аргумент внутри React.memo()?

    0xD34F
    @0xD34F Куратор тега React
    Открываем документацию и видим, что

    React.memo затрагивает только изменения пропсов. Если функциональный компонент обёрнут в React.memo и использует useState, useReducer или useContext, он будет повторно рендериться при изменении состояния или контекста.
    Ответ написан
    Комментировать
  • Как написать условие на подсчет одинаковых соседних символов в строке?

    0xD34F
    @0xD34F
    import re
    
    def has_consecutive_characters(s, count):
      return bool(re.search(rf'([\dA-Z])\1{{{count - 1}}}', s, re.IGNORECASE))
    
    
    arr = [
      'PAaAssword',
      'Paaaassword',
      'P111ssword',
      'Password',
    ]
    
    print([ has_consecutive_characters(n, 3) for n in arr ])
    Ответ написан
    8 комментариев
  • Как правильно скрестить 3 массива в один?

    0xD34F
    @0xD34F Куратор тега JavaScript
    const merge = (key, ...arrs) =>
      Object.values(arrs.flat().reduce((acc, n) => (
        Object.assign(acc[n[key]] ??= {}, n),
        acc
      ), {}));
    
    
    const result = merge('id', arr1, arr2, arr3);
    Ответ написан
    Комментировать
  • Как можно сделать функцию перебора объекта проще/чистой?

    0xD34F
    @0xD34F Куратор тега JavaScript
    Проще - используйте возможности массивов более полно:

    const getTruthyKeys = obj =>
      Object
        .entries(obj)
        .filter(n => n[1])
        .map(n => n[0]);

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

    for([key, value] of Object.entries(item)) {


    UPD. А вообще, если подумать, то такая функция чистой быть не может. Уж точно не в js.
    Потому что в js можно сделать так:

    const obj = new Proxy({
      a: 0,
      b: 1,
      c: 2,
    }, {
      get: () => Math.round(Math.random()),
    });

    Ну и соответственно, результаты будут случаться для такого объекта самые разные:

    console.log(Array.from({ length: 10 }, () => getTruthyKeys(obj)));

    Ответ написан
    4 комментария
  • Как во Vue подождать загрузки чего-то и только после успешной загрузки позволить навесить обработчик click?

    0xD34F
    @0xD34F Куратор тега Vue.js
    Вот не надо этой ерунды с жонглированием обработчиками.

    Пусть кнопка будет неактивной, пока данных нет:

    <button :disabled="!данные" @click="onClick">

    Заодно и пользователь, вместо того, чтобы испытывать недоумение по поводу отсутствия какой-либо реакции на свои действия, будет ясно видеть, что кликать по кнопке не то, что не надо - бессмысленно.
    Ответ написан
    Комментировать
  • Как изменить вложенное свойство через сцепление во vue?

    0xD34F
    @0xD34F Куратор тега Vue.js
    computed: {
      model() {
        return new Proxy(Object.fromEntries(this.obj2.map(n => [ n.model, null ])), {
          get: (target, prop) => typeof prop === 'string'
            ? prop.split('.').reduce((p, c) => p?.[c], this.obj)
            : target[prop],
          set: (target, prop, value) => {
            const keys = prop.split('.');
            const key = keys.pop();
            const obj = keys.reduce((p, c) => (!p.hasOwnProperty(c) && this.$set(p, c, {}), p[c]), this.obj);
            this.$set(obj, key, value);
            return true;
          },
        });
      },
    },

    <div v-for="(v, k) in model">
      <input v-model="model[k]">
    </div>

    https://jsfiddle.net/34brtvok/

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

    computed: {
      model() {
        return this.obj2.map(n => {
          const keys = n.model.split('.');
          const key = keys.pop();
          const obj = keys.reduce((p, c) => p?.[c], this.obj);
    
          return obj && { obj, key };
        }).filter(Boolean);
      },
    },

    <div v-for="n in model">
      <input v-model="n.obj[n.key]">
    </div>

    https://jsfiddle.net/34brtvok/1/
    Ответ написан
    Комментировать
  • Как выбрать все элементы, кроме первого и последнего?

    0xD34F
    @0xD34F Куратор тега CSS
    li:not(:first-child, :last-child)

    или

    li:not(:first-child):not(:last-child)

    или

    li {
      /* тут стили для всех элементов */
    }
    li:first-child,
    li:last-child {
      /* здесь сбрасываете стили, установленные выше */
    }

    https://jsfiddle.net/6zxdwear/
    Ответ написан
    Комментировать
  • Почему компонент не перерисовывается?

    0xD34F
    @0xD34F Куратор тега React
    Вызов switchPatternTable внутри обработчика клика - зачем он там? Да ещё и результат улетает в никуда.

    Вызов switchPatternTable в "нужном участке страницы" - во-первых, параметр не передаётся, т.е., результат всегда будет один и тот же; во-вторых, из показанного огрызка неясно, что с этим результатом происходит дальше.

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

    0xD34F
    @0xD34F Куратор тега JavaScript
    const replaceValues = (val, test, replacer) =>
      val instanceof Array
        ? val.map(n => replaceValues(n, test, replacer))
        : val instanceof Object
          ? Object.fromEntries(Object
              .entries(val)
              .map(([ k, v ]) => [
                k,
                test(k, v)
                  ? replacer(v)
                  : replaceValues(v, test, replacer)
              ])
            )
          : val;
    
    
    const newData = replaceValues(
      data,
      k => k.includes('Date'),
      v => v.replace(/(\d+)-(\d+)-/, '$2.$1.')
    );
    Ответ написан
    6 комментариев
  • Как достать из текста данные в таком виде с помощью PHP?

    0xD34F
    @0xD34F Куратор тега Регулярные выражения
    preg_match_all('~\[(.+?)\|(.+?)\]~', $str, $matches);
    Ответ написан
  • Как из объекта Proxy извлечь данные?

    0xD34F
    @0xD34F Куратор тега Vue.js
    Точно так же, как если бы вместо Proxy у вас был оригинальный объект (кстати, а почему вы этого не попробовали сделать - что, увидели этот непонятный Proxy и испугались?).

    Vue заворачивает данные в Proxy для отслеживания изменений. Если вдруг очень надо, можно получить оригинальные данные с помощью toRaw.

    получить массив

    А где у вас там массив? Никакого массива нет. Или исправляйте код на сервере, чтобы присылались верные данные, или используйте Object.values.
    Ответ написан
    Комментировать
  • Как удалить элемент массива и сменить оставшиеся ключи на 1 меньше?

    0xD34F
    @0xD34F
    Получить массив с правильными индексами можно с помощью array_values.

    Правда, с учётом решаемой вами задачи...

    присвоить первому массиву значения второго только без первого элемента

    ...вам это не потребуется - используйте array_slice вместо той ерунды с unset.
    Ответ написан