• Какой подход к проектированию бэкенда лучше? В чем принципиальная разница между подходами?

    AlexNest
    @AlexNest
    Работаю с Python/Django
    Есть ли принципиальная разница между этими подходами?

    Ну, как бы да - в первом случае используются классы, во втором - функции. В этом
    какой подход правильнее использовать. Пока возникает ощущение, что всё это - сугубо вкусовщина.

    Это, имхо, вопрос размера проекта и сложности ориентирования в нем. То есть, для простой КРУД-ориентированной системы классы могут быть излишни. Но чем больше логики вынесено за пределы "чтения-записи" из БД, тем ощутимее нужны будут классы.
    И какие еще есть подходы

    Есть еще процедурное, но оно сейчас используется исключительно для простых программ и на скриптовых языках по типу питона и ванильного js.
    Ответ написан
    Комментировать
  • Зачем нужна перегрузка функций?

    bingo347
    @bingo347 Куратор тега TypeScript
    Crazy on performance...
    Перегрузки нужны в следующих случаях:
    1. Когда от типа некоторого аргумента зависит тип возвращаемого значения;
    2. Когда от типа некоторого аргумента зависят типы последующих аргументов;
    3. Комбинация из 1 и 2 вариантов.

    Важно понимать, что в TS перегрузки существуют только на уровне типов, в отличии от других языков. Притом сами перегрузки реализованы как intersection от всех сигнатур, что порой вызывает проблемы с присвоением функции к типу с перегруженной сигнатурой. Все дело в вариантности, так как аргументы функции контравариантны сигнатуре самой функции, когда большинство отношений типов (и intersection в том числе) в TS ковариантны. В вашем примере с SumOrConcat эту проблему решили через тип any, который делает любую композицию типов с ним бивариантной.

    На самом деле в примере с SumOrConcat вполне можно задать типы аргументам:
    type SumOrConcat = {
      (a: number, b: number): number
      (a: string, b: number): string
    }
    
    const result: SumOrConcat = (a: number | string, b: number): any => {
      if (typeof a === 'number') {
        return a + b
      }
    
      return `${a} ${b}`
    }
    Но надежнее все же так:
    type SumOrConcat = {
      (a: number, b: number): number
      (a: string, b: number): string
    }
    
    const result = ((a: number | string, b: number): number | string => {
      if (typeof a === 'number') {
        return a + b
      }
    
      return `${a} ${b}`
    }) as SumOrConcat;
    Ну и надо отметить, что синтаксис самих перегрузок таких проблем не имеет, хотя стрелочную функцию с ним не опишешь
    function sumOrConcat(a: number, b: number): number;
    function sumOrConcat(a: string, b: number): string;
    function sumOrConcat(a: number | string, b: number): number | string {
      if (typeof a === 'number') {
        return a + b
      }
    
      return `${a} ${b}`
    }
    
    const result = sumOrConcat;


    Так же, очень часто можно обойтись без перегрузки используя дженерики. Сам такой код будет выглядеть сложнее, но пользоваться им будет проще. Пример.
    Ответ написан
    1 комментарий
  • Как сохранить JSON в MongoDB с сохранением связей?

    Ну или, может, какие-то другие варианты есть?

    Есть. Использовать каждую СУБД по назначению и не пытаться запихнуть реляционные данные в документную БД.

    А вообще, наверное стоит просто для независимых сущностей генерировать новые ObjectId, и протаскивать их во все зависимые сущности вместо соответствующих id. Ну т.е. не нужно пытаться решать задачу в лоб, пытаясь сконвертировать один id в другой, вам нужно сконвертировать СВЯЗЬ, а не id. Чтобы сконвертировать связь, вам не нужен оригинальный id, вам важно соединить с помощью нового ObjectId те же самые сущности, что были соединены в реляционной базе оригинальным id.
    Ответ написан
    1 комментарий
  • Как связать Nuxt и CMS?

    delphinpro
    @delphinpro Куратор тега PHP
    frontend developer
    Совет простой — учитесь.
    Всё очень сумбурно, ничего непонятно. Как устроено, как настроено...
    Можно включить режим гадалки. Кто-то так и сделает и будет давать советы. Может они вас наведут в нужное русло...

    Давайте сначала.
    Что такое "headless-cms"? по сути это cms в режиме API. Получает запрос, отдает голые данные. Чаще всего в формате json.

    Что из этого следует?
    Это значит у вас два приложения. Серверная часть на cms. И клиентская на vue.
    Первая работает на php, вторая на nodejs.

    Значит вы на своем сервере (машине) должны поднять два сервера (программных). Один будет обрабатывать запросы к данным (API/cms), другой висеть на 80 дефолтном порту (ваш фронт на VUE) и брать данные из первого.

    Что касается nuxt, то он может работать в режимах SSR и без него. Если без, то все сводится к тому, чтобы скопировать ваш index.html из билда в основной шаблон CMS. Если с SSR, то придется поднимать доп. nodejs сервер и разруливать запросы nginx'oм. 80-й порт на nodejs, кастомный - на php cms.
    Ответ написан
    3 комментария
  • Где брать координаты для построения Polygon в Mapbox, Google maps etc?

    freeExec
    @freeExec
    Участник OpenStreetMap
    Накликайте свой полигон в geojson.io и подставьте туда.
    Ответ написан
    1 комментарий
  • Какое регулярное выражение использовать для валидации числа по нижеуказанным требованиям?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    Какое регулярное выражение использовать для валидации числа по нижеуказанным требованиям?
    Никакое, ибо не зачем.

    Валидация делается по событиям keyup и paste
    Почему бы не городить костыли и просто не использовать событие input?

    input с type="number" уже отсеет невалидные символы, хотя валидное число будет далеко не обязательно
    Ответ написан
    4 комментария
  • Как сделать рекурсивный последовательный async-await?

    0xD34F
    @0xD34F Куратор тега JavaScript
    Последовательно:

    async function fetchRecursive(arr) {
      const result = [];
    
      if (Array.isArray(arr)) {
        for (const n of arr) {
          try {
            result.push({ status: true, result: await fetch(n.url).then(r => r.json()) });
          } catch(error) {
            result.push({ status: false, error });
          }
    
          result.push(...await fetchRecursive(n.children));
        }
      }
    
      return result;
    }

    Параллельно:

    const flat = arr => (arr || []).flatMap(n => [ n.url, ...flat(n.children) ]);
    
    const fetchRecursive = arr => Promise.allSettled(flat(arr).map(n => fetch(n).then(r => r.json())));
    Ответ написан
    1 комментарий
  • Как составить такое регулярное выражение?

    john36allTa
    @john36allTa
    alien glow of a dirty mind
    Может это поможет или хоть натолкнет на мысль
    function format(value){
    	let [a,b] = (+value.replace(/[^\d\.,]/g,'').replace(',','.')).toFixed(2).split('.')
    		c = a.replace(/(\d)(?=(\d{3})+(\D|$))/g, '$1 ')
    	return `${c},${b}`
    }
    
    console.log(format('12734,589'))
    // 12 734,59
    console.log(format('1 2 7  3s4.5'))
    // 12 734,50
    console.log(format('12734'))
    // 12 734,00

    Если хотите всё же ограничить пользователя в вводе по формату, то просто сделайте
    <input type="text" id='price' placeholder="12 345,90" required pattern="^\d{1,3}(\s?\d{3})*([\.,]\d+)?$" />


    Ну или что то вроде такого:
    Ответ написан
    1 комментарий
  • Как передать в компонент из vuex изменившиеся данные конкретного объекта store?

    kulakoff
    @kulakoff Куратор тега Vue.js
    Vue.js developing
    Попробуйте заменить мутацию на такую:
    startMutation(state, data) {
      const index = state.listings.findIndex(item => item.id === data.id)
      state.listings.splice(index, 1, {...state.listings[index], is_edited: true})
    }
    Ответ написан
    2 комментария
  • Действительно ли reduce, filter, map и прочие работают медленнее обычного for?

    dom1n1k
    @dom1n1k
    Да, действительно все эти методы работают медленнее обычного for.
    Безусловно медленнее и так будет всегда. Никакой прогресс JS-компиляторов не изменит этой ситуации. Оптимизации компиляторов могут только уменьшать отставание данных методов от простого цикла, но никогда не сделает их равными и уж тем более быстрее. Преимущество этих методов не в скорости, а исключительно в читаемости кода и то при условии разумного применения.
    Но всегда нужно смотреть по ситуации. Может у вас массив из 10 элементов и ваша потенциальная экономия это 1 микросекунда? В большинстве случаев (хотя и не всегда) проигрыш производительности будет пренебрежимо мал.
    Но если вы обоснованно считаете, что перфоманс вам критически важен - конечно, используйте for.
    Ответ написан
    Комментировать
  • Действительно ли reduce, filter, map и прочие работают медленнее обычного for?

    iCoderXXI
    @iCoderXXI
    React.JS/FrontEnd engineer
    Методы массивов на вход получаются коллбек, потом его вызывают, получают обратно значения.

    Многие из коллбеков создают и заполняют новый массив. Это всё накладные расходы.
    Ответ написан
    Комментировать
  • Действительно ли reduce, filter, map и прочие работают медленнее обычного for?

    Xuxicheta
    @Xuxicheta
    инженер
    Сегодня быстрее, завтра не быстрее, послезавтра быстрее.
    Перфоманс таких вещей зависит от реализации js и будет разным на разных движках и версиях.
    Без веских причин не стоит экономить на спичках жертвуя читабельностью.
    Будь методы перебора массивов не нужны, их не сделали бы, правда ведь?
    Ответ написан
    6 комментариев
  • Действительно ли reduce, filter, map и прочие работают медленнее обычного for?

    Taraflex
    @Taraflex
    Ищу работу. Контакты в профиле.
    Можно заинлайнить
    https://github.com/vzhou842/faster.js
    Ответ написан
    Комментировать
  • Действительно ли reduce, filter, map и прочие работают медленнее обычного for?

    xmoonlight
    @xmoonlight
    https://sitecoder.blogspot.com
    Всё из-за постоянных проверок типов данных.
    Хотите быстро - нативный js
    Хотите очень быстро - c++ либы через emscripten.
    Ну, и не кривые алгоритмы, разумеется.
    Ответ написан
    3 комментария
  • Действительно ли reduce, filter, map и прочие работают медленнее обычного for?

    @grinat
    Ну а чо тут удивительного? Как бэ это очевидно. Ну на маленьких массивах это не заметно и смысла нет запариваться, если массив большой, то разница всегда очень приличная. Да и сортировка встроенная в js не всегда самая быстрая и т.д. В любом случае львиная доля js разрабов с такими задачами врядли столкнется. Да и зачем в этом разбираться, алгоритмы жеж для лохов.
    Ответ написан
    2 комментария
  • Почему vue-router не меняет данные в компоненте?

    0xD34F
    @0xD34F Куратор тега Vue.js
    Потому что экземпляр компонента заново не создаётся при смене значений параметров. За ними надо следить:

    watch: {
      '$route.params.slug': {
        immediate: true,
        handler() {
          // сюда переносите код из created
        },
      },
    },
    Ответ написан
    1 комментарий
  • Как правильно работать с props во Vue.js?

    origami1024
    @origami1024
    went out for a night walk
    Вот официальная схема. Родители детям через props, назад через events.
    5dbadb9101ea4780880983.png

    1) Пример объявления child в template родителя
    <child :somedata="data1" @bestEventEver="someMethod"/>

    -передаешь данные из переменной родителя data1 чилду в пропс somedata.
    -вешаешь метод родителя someMethod для обработки кастомного ивента 'bestEventEver', приходящего из чилда

    2) В child вызываешь this.$emit('bestEventEver', 'params pam pams')

    Есть сокращения этого для простых случаев через :v-model и .sync, читай официальный гайд

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

    Если нужно общение не уровня родитель-ребенок, а все со всеми, вот варианты
    Ответ написан
    Комментировать
  • Как использовать разные компоненты в одном шаблоне vue?

    delphinpro
    @delphinpro
    frontend developer
    Дофига лишний компонентов на первый взгляд..
    Но фиг с ним. Пилите роутер-вью на месте меняемых компонентов:

    <div id="app">
        <router-view></router-view>
    </div>
    
    <main class="main">
        <app-aside></app-aside>
        <router-view></router-view>
    </main>
    
    <section class="app__section">
        <section-header></section-header>
        <router-view></router-view>
    </section>


    Ну а дальше изучать https://router.vuejs.org/ru/guide/essentials/neste...
    Ответ написан
    1 комментарий
  • Как уникализировать массив объектов по значениям нескольких свойств?

    0xD34F
    @0xD34F Куратор тега JavaScript
    Вот вариант максимально короткий и лёгкий для понимания:

    const unique = (arr, keys) =>
      arr.filter(n => n === arr.find(m => keys.every(k => m[k] === n[k])));
    
    
    const result = unique(arr, [ 'model', 'param1', 'param2' ]);

    Для вашего случая подходит, но вообще, есть ряд проблем:
    • Иногда косячит

      Если объект присутствует в массиве несколько раз, то такие дубликаты не будут отброшены. Конкретно эта имеет тривиальное решение - вместо ссылок можно сравнивать индексы, под которыми объекты представлены в массиве:

      - arr.filter(n => n === arr.find
      + arr.filter((n, i, a) => i === a.findIndex
    • Недостаточно гибко

      Что если уникализировать надо не по собственно свойствам, а по каким-то производным от них значениям? Например, у объектов есть вложенные объекты, и нужны их свойства; или есть число, а нужен остаток от его деления на какое-то другое число; или есть дата, в которой важен только месяц.
    • Сложность

      Фильтрация линейна, поиск тоже, одно внутри другого даёт квадрат.

    Так что вот вариант потяжелее:

    const unique = function(arr, keys = n => n) {
      const picked = new Map;
      return arr.filter((...args) => {
        const p = []
          .concat(keys(...args))
          .reduce((acc, k) => acc.set(k, acc.get(k) || new Map).get(k), picked);
    
        return !p.set(this, p.has(this)).get(this);
      });
    }.bind(Symbol());
    
    
    const result = unique(arr, n => [ n.model, n.param1, n.param2 ]);
    Ответ написан
    2 комментария