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

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    Задача проверки последовательности на палиндром решается за O(n/2). Но для этого нужно иметь последовательный доступ к обоим концам последовательности за O(1).
    Если такой возможности нет и имеется доступ только к одному из концов последовательности, то придется обойти всю последовательность, а это уже O(n). Один из таких, достаточно оптимальных алгоритмов для цифр целого числа уже представил WbICHA.

    Чтоб решить эту задачу за O(n/2) нужно понять, как получить крайние цифры числа за O(1).
    Крайнюю справа цифру можно получить простым остатком от деления на основание системы счисления, то есть, в случае десятичной системы счисления, на 10.
    Для получения крайней справа цифры нужно знать ее порядок (считая справа начиная с 0). Это можно сделать взяв целую часть от логарифма по основанию системы счисления (10). На JS такая операция будет выглядеть так:
    Math.trunc(Math.log10(num))
    Целая часть от деления числа на 10 в степени порядка правой цифры даст саму эту цифру. На JS это выражается так:
    Math.trunc(num / 10 ** Math.trunc(Math.log10(num)))

    Так же алгоритм требует равномерного перемещения по последовательности от краев к центру.
    Для правой цифры опять все просто, можно брать целую часть от деления числа на основание (10).
    Для левой нужно умножить ее на основание в степени порядка и вычесть результат из самого числа, то есть:
    num - leftDigit * 10 ** Math.trunc(Math.log10(num))


    Осталось учесть пограничные условия:
    1. Если крайний левый и крайний правый элемент не равны, то последовательность не является палиндромом
    2. Последовательность из одного элемента (число из одной цифры) всегда палиндром.
    3. При равенстве крайних элементов последовательность будет палиндромом если палиндромом так же является подпоследовательность без этих элементов.

    Пункт 3 подразумевает рекурсию, но такая рекурсия легко разворачивается в цикл, что конечно же более оптимально.

    По итогу получим такую функцию:
    const isPalindrome = num => {
        let n = num;
        while (n >= 10) {
            const order = 10 ** Math.trunc(Math.log10(n));
            const leftDigit = Math.trunc(n / order);
            const rightDigit = n % 10;
            if (leftDigit !== rightDigit) return false;
            n -= leftDigit * order;
            n /= 10;
            n = Math.trunc(n);
        }
        return true;
    };


    P.S. варианты с приведением числа к строке, а тем более с последующим разбиением на массив чисел и разворотом его, просто отвратительны.
    Приведение числа к строке - это O(n) если не больше, так как в JS тип number - это по сути float64 и алгоритм приведения учитывает, что число может быть с дробной частью.
    Разбиение строки на массив символов (split) - O(n) и требует доп памяти под этот массив.
    Реверс массива - O(n/2)
    Склейка (join) - опять O(n)
    Сравнение строк - еще раз O(n)
    И хотя суммарная сложность останется O(n), количество проходов по цифрам числа будет в 5 раз больше, хотя даже на строках можно уложится в 1.5 обхода:
    const isPalindrome = num => {
        const s = String(num);
        for (let i = 0; i < s.length / 2; i++) {
            if (s[i] !== s[s.length - i - 1]) return false;
        }
        return true;
    };
    Ответ написан
    4 комментария
  • Что хранит в себе данная функция?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    Комментировать
  • Как получить счастливое число?

    Aetae
    @Aetae Куратор тега JavaScript
    Тлен
    Тут всё плохо:
    function isHappy(array){
      // записываем пустой массив в array
      // (не важно что там мы получили, теперь этого нет)
      array = [] 
      // получаем 6 переменных с значением "ничего"(undefined)
      let[x,y,z,b,n,v] = array
      // сравниваем x+y+z == b+n и выкидываем, никак не используя
      // с помощью оператора запятая(,) в if попадает только v
      // как мы знаем во всех переменных undefined - if(undefined) - ложь
      if(x+y+z == b+n,v){
        console.log(`Число ${array} - счастливое!`);
      }
      else{
        console.log(`Число ${array} - несчастливое`);
      }
    }
    // вызываем isHappy с аргументом 000000, который является числом 0, 
    // просто записанным длинно, а не массивом
    isHappy(000000)
    Ответ написан
    8 комментариев
  • Какой факультет выбрать веб программисту?

    @Everybody_Lies
    Не ищи вуз где тебя научат кодить, выбирай любой инженерный или математический факультет, просто для прокачки мозгов.
    Все навыки для разработки всё равно будешь изучать самостоятельно.
    Ответ написан
    Комментировать
  • Ценятся ли программисты-самоучки в странах Евросоюза?

    sergey-gornostaev
    @sergey-gornostaev
    Седой и строгий
    Ценятся профессионалы, всем плевать, как этот профессионализм был получен. Но надо понимать, во-первых, что желающих получить blue card много, а мест мало. Поэтому вам придётся конкурировать с целой кучей профессионалов и при прочих равных шансов больше будет у обладателей дополнительной бумажки. Во-вторых, интерес западных работодателей начинается на том уровне профессионализма, который у очень выдающихся программистов достигается лет через пять работы, а у остальных через десять. То есть ваш год самообразования - вообще ничто.

    P.S. Вопрос на ресурсе задавался уже очень много раз. Для программиста критически важно уметь искать информацию самостоятельно.
    Ответ написан
    8 комментариев
  • Как написать функцию TypeScript?

    bingo347
    @bingo347 Куратор тега TypeScript
    Crazy on performance...
    Что-то вроде такого можно сделать:
    type TestResult<T extends string[] | CustomClass[]> = T extends CustomClass[] ? T : void;
    function test<T extends string[] | CustomClass[]>(data: T): TestResult<T> {
        if (data[0] instanceof CustomClass) {
          return data as TestResult<T>;
        }
    
        return undefined as TestResult<T>;
    }

    https://www.typescriptlang.org/play?#code/CYUwxgNg...

    Но без приведения типов внутри не обойтись. Ну и как писал WbICHA в комментах, такие типы не безопасны для пустого массива, так как в рантайме типов нет, а значит и нет возможности проверить, какого типа пришел пустой массив.
    Ответ написан
    1 комментарий
  • Я так никогда не выучу React. Что это за ошибка?

    tsepen
    @tsepen
    Frontend developer
    Нельзя выучить Реакт не выучив Джаваскрипт, рекомендую начать с JS, иначе дальше тебя ждет еще очень много сюрпризов
    Ответ написан
    Комментировать
  • Как правильно реализовать дженерик?

    Aetae
    @Aetae Куратор тега TypeScript
    Тлен
    typescriptlang.org/play
    spoiler
    type Alph = 'Q' | 'W' | 'E' | 'R' | 'T' | 'Y' | 'U' | 'I' | 'O' | 'P' | 'A' | 'S' | 'D' | 'F' | 'G' | 'H' | 'J' | 'K' | 'L' | 'X' | 'Z' | 'C' | 'V' | 'B' | 'N' | 'M'
    
    type CamelToSnake<T extends string> = T extends `${infer S1}${Alph}${string}` ? T extends `${S1}${infer S2}` ? `${Lowercase<S1>}_${CamelToSnake<Uncapitalize<S2>>}` : T : T;
    type AsdSnake = CamelToSnake<'asdAsdAsd'> // asd_asd_asd
    
    type SnakeToCamel<T extends string> = T extends `${infer S1}_${infer S2}` ? `${Lowercase<S1>}${Capitalize<SnakeToCamel<S2>>}` : T;
    type AsdCamel = SnakeToCamel<'asd_asd_asd'> // asdAsdAsd
    
    type SnakePropToCamel<T extends PropertyKey> = T extends string ? SnakeToCamel<T> : T;
    type CamelPropToSnake<T extends PropertyKey> = T extends string ? CamelToSnake<T> : T;
    
    let camelToSnakeCase: <T extends PropertyKey>(str: T) => CamelPropToSnake<T>;
    
    type CamelObjectToSnake<T extends {[key: string]: any}> = {
      [K in keyof T as CamelPropToSnake<K>]: T[K]
    }
    
    function camelCaseObject<T extends {[key: string]: any}>(obj: T) {
      return Object.entries(obj)
        .reduce((acc, [key, value]) =>
            (acc[camelToSnakeCase(key as keyof T)] = value, acc),
          {} as CamelObjectToSnake<T>
        )
    }
    
    function camelToSnakeKeysOfArrayObject<T extends Array<{[key: string]: any}>>(arr: T) {
      return arr.map(camelCaseObject) as {
        [K in keyof T]: CamelObjectToSnake<T[K]>
      };
    }

    Основано на варианте WbICHA но поддерживает объекты разных сигнатур, типа:
    camelToSnakeKeysOfArrayObject([{
      aaAa: 1,
      bbBb: true
    }, {
      aaAa: 'ggg'
    }]);
    Ответ написан
    8 комментариев
  • Как исправить ошибку "No overload matches this call" в jest.spyOn на приватном методе?

    bingo347
    @bingo347 Куратор тега TypeScript
    Crazy on performance...
    jest.spyOn имеет 4 перегрузки, которые отделяют обычные поля (в этих перегрузках есть 3й параметр 'get' | 'set'), методы (функциональный тип на инстансе) и static методы (функциональный тип на самом классе).
    Ваш вызов подразумевает как раз метод.
    Проблема в том, что private и protected поля не матчатся как функциональные типы. Приватные поля вообще не имеют типа за пределами класса, а protected имеют тип только в наследнике.

    Остается только обмануть систему типов:
    declare class ViewHack {
      getPosOnScale(currentPos: number): number;
    }
    describe('some method', () => {
      test('should return smth', () => {
        const view = new View('range-slider', settings);
        jest.spyOn(view as unknown as ViewHack, 'getPosOnScale').mockReturnValue(100);
      });
    });
    Ответ написан
    2 комментария
  • Какой алгоритм вычисления кратности чисел более эффективен?

    Adamos
    @Adamos
    Если нужно определить кратность - то берем учебник Математика, 6 класс.
    Глава Признаки кратности 3, 5 и 9 с минимумом вычислений.
    Если же нужно заполнить массив - то потери времени на его заполнение, да в жабоскрипте, на порядки превышают стоимость этой простенькой проверки.
    Может ускорить (а может и замедлить) этот процесс замена в цикле ++i на прибавление того числа, которое действительно надо прибавить для получения следующего кратного - оно циклично повторяется: [3, 2, 1, 3, 1, 2, 3]. Проверка уберется, но вычислений, на самом деле, только прибавится. Зато без ветвления и пустых циклов.
    Ответ написан
    1 комментарий
  • Где ошибка в коде?

    Rsa97
    @Rsa97
    Для правильного вопроса надо знать половину ответа
    Ошибка в коде ДНК.
    Вставить в PHP фрагмент кода на JavaScript и надеяться, что он заработает - это надо быть альтернативно одарённым человеком.
    Ответ написан
    1 комментарий
  • Почему let x не попадает в window?

    delphinpro
    @delphinpro Куратор тега JavaScript
    frontend developer
    Мужик, ну ты хотя бы документацию прочитай, прежде чем вопрос задавать!!!

    Вот с MDN цитата

    На верхнем уровне скриптов и функций let, в отличии от var, не создаёт свойства на глобальном объекте.


    ДОКУМЕНТАЦИЯ!!! – наше всё.
    Ответ написан
    13 комментариев
  • Что сделать, чтобы найти тот самый «баланс»?

    sergey-gornostaev
    @sergey-gornostaev
    Седой и строгий
    1. Лучше иметь вышку, чем не иметь.
    2. В 99.99% случаев вышка не нужна для работы.
    3. Вышка облегчает поиск первой работы.
    4. Вышка не нужна для эмиграции.

    Доучивайтесь в школе, поступайте в ВУЗ, после первого же семестра начинайте искать летнюю стажировку, пытайтесь устроиться в университетский ВЦ или на кафедру, договаривайтесь курса с 4-го на свободное посещение занятий и выход на полную ставку. Посвящайте свободное время не математике, а изучению прикладных знаний и практике.
    Ответ написан
  • Какие ЯП являются (почти) "мертвыми" и бесперспективными?

    @evgeniy_lm
    Мне лично на ум приходит такие как VBA

    Несколько лет назад общался с одним чудиком который возмущался тем что он "крутой программист" знает туеву хучу "крутых ЯП", но не может найти работу, а его "тупой" одноклассник в буржуйской фирме зашибает бабло на "сраном VBA"

    Не существует "бесперспективных" ЯП, существуют бесперспективные программисты
    Ответ написан
    Комментировать
  • Как получить массив массивов с 2-мя объектами из 2-ух массивов с объектами?

    0xD34F
    @0xD34F Куратор тега JavaScript
    Не будем ограничиваться двумя массивами, решим задачу в более общем виде - пусть источников данных будет произвольное количество. Возможны разные варианты:

    1. Если уверены, что длины всех массивов будут равны:

      const zip = (...arrs) =>
        arrs[0]?.map((n, i) => arrs.map(m => m[i])) ?? [];
      
      const result = zip(arr1, arr2);


    2. Вместо отсутствующих значений подставляем какое-то дефолтное:

      const zip = (arrs, defaultValue = null) =>
        Array.from(
          { length: Math.max(...arrs.map(n => n.length)) },
          (n, i) => arrs.map(m => i < m.length ? m[i] : defaultValue)
        );
      
      // или
      
      const zip = (arrs, defaultValue = null) =>
        arrs.reduce((acc, n, i) => (
          n.forEach((m, j) => (acc[j] ??= Array(arrs.length).fill(defaultValue))[i] = m),
          acc
        ), []);

      В вашем случае применять, понятное дело, так: const result = zip([ arr1, arr2 ]);.

      Пример с разными длинами массивов - zip([ [ 1, 2, 3 ], [], [ 99 ] ], Infinity) - в результате получим

      [
        [ 1, Infinity,       99 ],
        [ 2, Infinity, Infinity ],
        [ 3, Infinity, Infinity ]
      ]


    3. В качестве источников данных могут выступать не обязательно массивы:

      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 = [...zip([ arr1, arr2 ])];.

      Пример посложнее, результатом выражения

      Array.from(zip((function*() {
        yield [ , true, false, NaN ];
        yield 'abcde';
        yield Array(3).keys();
      })()))

      будет следующий массив:

      [
        [ undefined, 'a',    0 ],
        [      true, 'b',    1 ],
        [     false, 'c',    2 ],
        [       NaN, 'd', null ],
        [      null, 'e', null ]
      ]


    Ответ написан
    1 комментарий
  • Как убедить тайпскрипт, что unknown можно в ReturnType?

    bingo347
    @bingo347 Куратор тега TypeScript
    Crazy on performance...
    У TypeScript есть ряд проблем с функциональными типами в дженериках из-за их вариантности
    Вот так результат будет аналогичным, но работает без проблем:
    function call<R>(f: () => R): R {
      return f()
    }
    Ответ написан
    5 комментариев
  • Стоит ли идти в NoCode разработку?

    saboteur_kiev
    @saboteur_kiev Куратор тега Карьера в IT
    software engineer
    NoCode это инструменты для тех, кто не умеет кодить, но готов потратить немного времени чтобы сделать какую-то штуку сам для себя.
    Специалисты по NoCode не нужны вообще.
    Если кто-то сделал свой "бизнес" и решил сделать себе сайт-визитку, то благодаря NoCode, не особо криворуким рукам и невысоким требованиям к конечному результату, он сможет сам ее себе сделать в одном из тысяч конструкторов.
    Но такому бизнесмену ты вообще не нужен.

    Поэтому твой вопрос глуп сам по сути. NoCode - это возможность сделать что-то простенькое для себя не привлекая разработчиков вообще и экономя на этом деньги. Зарабатывают в NoCode только создатели подобных конструкторов.
    Ответ написан
    Комментировать
  • Стоит ли идти в NoCode разработку?

    inoise
    @inoise Куратор тега Карьера в IT
    Solution Architect, AWS Certified, Serverless
    No code это не разработка
    Ответ написан
    Комментировать
  • Стоит ли идти в NoCode разработку?

    BorLaze
    @BorLaze
    Java developer
    Как бы вайти в айти, но так, чтобы не учить ничего по айти?
    Ответ написан
    Комментировать
  • Как из массива объектов, вытащить значение по ключу?

    0xD34F
    @0xD34F Куратор тега JavaScript
    Одно значение (первое):

    const val = arr.find(n => n.hasOwnProperty(key))?.[key];

    Все, что есть:

    const vals = arr.reduce((acc, n) => (n.hasOwnProperty(key) && acc.push(n[key]), acc), []);
    Ответ написан
    Комментировать