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

    0xD34F
    @0xD34F Куратор тега JavaScript
    const result = arr.map((n, i) => n * matrix.reduce((acc, row) => acc + row[i], 0));

    или

    const result = Array(arr.length).fill(0);
    
    for (const row of matrix) {
      for (const [ i, n ] of row.entries()) {
        result[i] += n * arr[i];
      }
    }
    Ответ написан
    Комментировать
  • Как вывести результат "на лету"?

    0xD34F
    @0xD34F Куратор тега JavaScript
    Вместо click'а у кнопки обрабатывайте input у формы:

    - document.querySelector('.calculate').addEventListener('click', function () {
    + document.querySelector('form').addEventListener('input', function () {
    Ответ написан
    6 комментариев
  • Как избавиться от двойных кавычек, выводя текущее количество введенных символов?

    0xD34F
    @0xD34F Куратор тега Vue.js
    Сообщение об ошибке, согласно документации yup, может быть указано в двух видах - строка или функция. Вычисляемое свойство является объектом, так что чего там с ним будет происходить - непонятно. Поэтому заменим вычисляемое свойство на функцию, которая будет извлекать его значение:

    .min(6, passwordMessage) ---> .min(6, () => passwordMessage.value)
    Ответ написан
    5 комментариев
  • Почему нет двусторонний привязки v-model?

    0xD34F
    @0xD34F Куратор тега Vue.js
    Потому что объект не реактивный. Надо в reactive завернуть.
    Ответ написан
    1 комментарий
  • Как рекурсивно обойти объект и выполнить get_object_vars?

    0xD34F
    @0xD34F
    public function expose() {
      return array_map(fn($n) => $n instanceof Text ? $n->expose() : $n, get_object_vars($this));
    }
    Ответ написан
    1 комментарий
  • Как передать в filter массив аргументов?

    0xD34F
    @0xD34F Куратор тега Vue.js
    Сделайте свои "аргументы" функциями, которые будут использоваться в качестве значений параметров метода filter, например:

    data: () => ({
      items: [ ... ],
      filters: [
        item => item.status === 'hello, world!!',
        item => item.price > 666,
        item => item.text.includes('fuck the world'),
      ],
    }),
    computed: {
      filteredItems() {
        return this.filters.reduce((items, filterFn) => items.filter(filterFn), this.items);
      },
    },
    Ответ написан
    Комментировать
  • Как, имея строку с ключами, получить массив значений из вложенных объектов?

    0xD34F
    @0xD34F Куратор тега JavaScript
    const result = Array
      .from(letter, n => soundParts[Number.isNaN(+n) ? 'letter' : 'number'][n])
      .filter(Boolean);

    или

    const result = Object
      .entries(Object.assign({}, ...Object.values(soundParts)))
      .reduce((acc, n) => (letter.includes(n[0]) && acc.push(n[1]), acc), []);
    Ответ написан
  • Как сортировать такой массив?

    0xD34F
    @0xD34F
    usort($lots, function($a, $b) use($currencyLists) {
      $ia = array_search($a['currency'], $currencyLists);
      $ib = array_search($b['currency'], $currencyLists);
      $t = $ia - $ib;
    
      return $t ? $t : ($a['lotSize'] - $b['lotSize']);
    });
    Ответ написан
  • Как получить подстроку в данном случае?

    0xD34F
    @0xD34F Куратор тега JavaScript
    str.match(/\]\s*(.+?)\s*#/)?.[1] ?? '< unknown >'
    Ответ написан
    Комментировать
  • Как обновить данные в vuex state?

    0xD34F
    @0xD34F Куратор тега Vue.js
    data(){
      return{
        Item: {
          ...

    v-model="item.name"

    Ну и как там у вас имя свойства начинается - с большой буквы или маленькой? Вы определитесь.

    ADD_TO_PRODUCTS({commit}, item){
        commit('SET_PRODUCT_TO_STATE', item)
    },

    methods:{
      ...mapActions([
          'ADD_TO_PRODUCTS',
      ]),

    @click="ADD_TO_PRODUCTS"

    В экшене ожидается параметр, но вы ничего не передаёте. Точнее, не передаёте в явном виде - передаётся объект события клика. А надо item (Item?).

    После того, как исправите косяки выше, у вас, вероятно, вылезет ещё один. С ним разбираться будете здесь.
    Ответ написан
    Комментировать
  • Как освоить vue.js?

    0xD34F
    @0xD34F Куратор тега Vue.js
    Читая документацию - сложно полностью понять её.

    Это потому что вы js не знаете. Если знать язык - понимать в документации нечего, всё становится ясно на ходу.

    Может ли это означать, что frontend не мое

    Может.

    либо это стандартная ситуация и стоить продолжать?

    Стандартная. Для не знающих js.

    Освоение фреймворков без знания языка - прямая дорога к превращению в говнокодера. Который никому на рынке труда конкуренции не составит. Если ваша цель такая - конечно продолжайте.

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

    0xD34F
    @0xD34F Куратор тега JavaScript
    const groupAdjacent = (arr, newGroup) =>
      arr.reduce((acc, n, i, a) => (
        (!i || newGroup(n, a[~-i])) && acc.push([]),
        acc.at(-1).push(n),
        acc
      ), []);
    
    
    const result = groupAdjacent(arr, (c, p) => c.name !== p.name);
    Ответ написан
  • Как сделать, чтобы выбранная дата была подсвечена в календаре?

    0xD34F
    @0xD34F Куратор тега Vue.js
    Оставить в datepicker'e просто дату, а дату с временем оформить как вычисляемое свойство.
    Ответ написан
    Комментировать
  • Почему в корзине считается только последний discount?

    0xD34F
    @0xD34F Куратор тега JavaScript
    for (let i in goods) {
      if (discounts.length === 0) {
        count = goods[i].value * goods[i].amount;
      }
      for (let j in discounts) {
        if (goods[i].name === discounts[j].name) {
          count =
            (goods[i].value - goods[i].value * discounts[j].discount) *
            goods[i].amount;
        } else {
          count = goods[i].value * goods[i].amount;
        }
      }
      sum += count;
      console.log(count, goods[i].name);
    }

    Зачем на каждой итерации цикла, ищущего скидку, пересчитывать цену? Предположим, нашли скидку для текущего товара, что дальше? Дальше, на следующей итерации, цена будет рассчитана заново, но уже без скидки - ведь объект скидки будет другим, будет соответствовать другому товару. Исключение - если скидка найдена на последней итерации.

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

    for (const n of goods) {
      let s = n.value * n.amount;
      for (const m of discounts) {
        if (n.name === m.name) {
          s *= 1 - m.discount;
          break;
        }
      }
      sum += s;
    }

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

    function totalCost(goods, discounts) {
      discounts = Object.fromEntries(discounts.map(n => [ n.name, 1 - parseFloat(n.discount) / 100 ]));
      return goods.reduce((acc, n) => acc + n.value * n.amount * (discounts[n.name] ?? 1), 0);
    }
    Ответ написан
    3 комментария
  • Как узнать индекс гласных в слове?

    0xD34F
    @0xD34F Куратор тега JavaScript
    Array.from(word.matchAll(/[aeiouy]/gi), n => n.index)

    или

    [...word.toLowerCase()].reduce((acc, n, i) => ('aeiouy'.includes(n) && acc.push(i), acc), [])

    или

    Object.entries(word).filter(n => 'AaEeIiOoUuYy'.indexOf(n[1]) !== -1).map(n => +n[0])


    Что до говнокода из вопроса...

    let letters = 'АаЕеIiOoUuYy'  //Создал переменную со строкой с гласными

    Почему символы из разных алфавитов? - первые четыре кириллические.

    if (arg1[i] == letters[j]) {  //Если элемент слова равен элементу строки с согласными
      newArr.push(arg1[i].indexOf())  //То пушу в массив индексы гласных этого слова
    }

    Какой ещё на хрен indexOf (кстати, вы не знаете, что он делает, откройте документацию и разберитесь)? Вот же бред. Что является индексом проверяемого символа? Строчкой выше ещё помнили, а когда до push'а дело дошло, уже забыли? Просто .push(i).

    Не ошибка, но упомянуть косячок стоит - после найденного совпадения продолжать крутить внутренний цикл смысла нет. Гуглите, как прервать цикл.
    Ответ написан
    Комментировать
  • Как сделать отмеченную форму checkbox устойчивой к обновлению страницы в браузере на Vue.js?

    0xD34F
    @0xD34F Куратор тега Vue.js
    Зачем отдельный массив checked? Пусть notes вместо массива строк будет массивом объектов, состоящих из двух свойств - text и checked. Наблюдатель c deep: true, сохраняющий данные в localStorage уже есть, так что никаких дополнительных действий предпринимать не придётся.

    UPD. Как это может выглядеть:

    <div id="app">
      <div>
        <input v-model="newTaskText" @keypress.enter="addTask">
        <button @click="addTask">add</button>
      </div>
      <hr>
      <ol v-if="tasks.length">
        <li v-for="(n, i) in tasks">
          <label :class="{ 'task-checked': n.checked }">
            <input type="checkbox" v-model="n.checked">
            {{ n.text }}
          </label>
          <button @click="delTask(i)">del</button>
        </li>
      </ol>
      <strong>Total: {{ tasks.length || 'no tasks fucking exist' }}</strong>
    </div>

    .task-checked {
      text-decoration: line-through;
    }

    Vue.createApp({
      data: () => ({
        newTaskText: '',
        tasks: JSON.parse(localStorage.getItem('tasks')) ?? [],
      }),
      watch: {
        tasks: {
          deep: true,
          handler: val => localStorage.setItem('tasks', JSON.stringify(val)),
        },
      },
      methods: {
        addTask() {
          const text = this.newTaskText.trim();
          if (text) {
            this.tasks.push({
              text,
              checked: false,
            });
    
            this.newTaskText = '';
          } else {
            alert('fuck off');
          }
        },
        delTask(index) {
          if (confirm('really?')) {
            this.tasks.splice(index, 1);
          }
        },
      },
    }).mount('#app');
    Ответ написан
    8 комментариев
  • Как объединить данные из двух массивов по id?

    0xD34F
    @0xD34F Куратор тега React
    const getData = type => fetch(`https://jsonplaceholder.typicode.com/${type}`).then(r => r.json());

    const [ data, setData ] = useState([]);
    
    useEffect(() => {
      Promise
        .all([ 'posts', 'users' ].map(getData))
        .then(([ posts, users ]) => {
          const usersObj = Object.fromEntries(users.map(n => [ n.id, n ]));
          setData(posts.map(n => ({
            post: n,
            user: usersObj[n.userId],
          })));
        });
    }, []);
    
    return (
      <div>
        {data.map(({ post, user }) => (
          <div>
            <h2>{post.title}</h2>
            <h3>{user.name}</h3>
            <p>{post.body}</p>
          </div>
        ))}
      </div>
    );
    Ответ написан
    1 комментарий
  • Как изменить цвет ссылки при наличии в ней определённого текста?

    0xD34F
    @0xD34F Куратор тега JavaScript
    Кого будем перекрашивать, и в какие цвета:

    const className = 'some-link';
    const colors = {
      En:   'red',
      Ru: 'green',
      De:  'blue',
    };

    Перекрашиваем текст в случае точного совпадения:

    for (const n of document.getElementsByClassName(className)) {
      n.style.color = colors[n.textContent];
    }

    Или, смотрим наличие подстроки, регистр не важен:

    document.querySelectorAll(`.${className}`).forEach(function(n) {
      n.style.color = this.find(m => m[0].test(n.innerText))?.[1];
    }, Object.entries(colors).map(n => [ RegExp(n[0], 'i'), n[1] ]));

    Можно и без регулярных выражений:

    - RegExp(n[0], 'i')
    + n[0].toLowerCase()

    - m[0].test(n.innerText)
    + n.innerText.toLowerCase().includes(m[0])
    Ответ написан
    Комментировать
  • Как записать рекурсию (функц. глубокого копирования) в виде цикла?

    0xD34F
    @0xD34F
    Используйте стек.

    Если, обрабатывая данные, натыкаетесь на объект, надо сохранить в стек текущее состояние - ссылку на копируемые данные, индекс текущего элемента, ссылку на объект, куда копируете; затем установить новое состояние - копируемыми данными будет массив пар ключ-значение встреченного объекта, индекс обнуляется (на самом деле надо выставить -1, нулевое значение будет получено при переходе к следующей итерации; конечно, можно и буквально 0 выставлять, но тогда придётся усложнить работу с индексом - тут увеличиваем, а тут нет), пустой объект в качестве копии.

    Если данные закончились, надо восстановить состояние из стека.

    Условий, при которых возможно продолжение цикла, будет два - кроме наличия необработанных данных ещё и непустой стек.

    function clone(value) {
      const clone = {};
      const stack = [];
    
      for (
        let i = 0, source = [ [ '', value ] ], target = clone;
        i < source.length || stack.length;
        i++
      ) {
        if (i === source.length) {
          [ i, source, target ] = stack.pop();
        } else {
          const [ k, v ] = source[i];
          const isObject = v instanceof Object;
    
          target[k] = isObject ? v.constructor() : v;
    
          if (isObject) {
            stack.push([ i, source, target ]);
            [ i, source, target ] = [ -1, Object.entries(v), target[k] ];
          }
        }
      }
    
      return clone[''];
    }

    Или, если в копируемом объекте могут быть циклические ссылки или какой-то из вложенных объектов встречается несколько раз и так же должно быть и в копии, то надо запоминать встреченные объекты, чтобы не обрабатывать их повторно - воспользуемся Map'ом, где ключами будут оригинальные объекты, а значениями их копии.

    Как выглядит получение копии объекта: проверяем, встречался ли указанный объект ранее, если нет - создаём новый объект, сохраняем его в Map, а также кладём его вместе с оригиналом в стек, для последующей обработки; достаём из Map'а копию.

    Крутим цикл, пока стек не пуст, на каждой итерации достаём из стека объект и его копию, перебираем свойства оригинала, записываем в копию копии значений.

    function clone(value) {
      const stack = [];
      const clones = new Map;
      const getClone = val => val instanceof Object
        ? (clones.has(val) || stack.push([ val, clones.set(val, val.constructor()).get(val) ]),
           clones.get(val))
        : val;
    
      for (getClone(value); stack.length;) {
        const [ source, target ] = stack.pop();
        Object.entries(source).forEach(n => target[n[0]] = getClone(n[1]));
      }
    
      return getClone(value);
    }

    как правильнее всего будет это сделать?

    Перестать заниматься ерундой и начать использовать готовые решения - structuredClone или cloneDeep, например.
    Ответ написан
    Комментировать
  • Как в библиотеке chart.js указать в оси Y два значение (минимальное и максимальное)?

    0xD34F
    @0xD34F
    options: {
      scales: {
        y: {
          ticks: {
            callback: (value, index, values) =>
              index > 0 && index < values.length - 1
                ? ''
                : Math[index ? 'max' : 'min'](...values.map(n => n.value)),
            ...
    Ответ написан
    2 комментария