Ответы пользователя по тегу Рекурсия
  • Как преобразовать имена свойств объекта из kebab-case в camelCase?

    bingo347
    @bingo347 Куратор тега TypeScript
    Crazy on performance...
    В дополнение к ответу 0xD34F нормальная типизация такой функции (нужен typescript 4.1 или выше):
    type AsCamelCase<S extends string> = S extends `${infer A}_${infer B}` ? `${A}${Capitalize<AsCamelCase<B>>}` : S;
    type CamelCaseKeysRecord<T> = T extends Record<PropertyKey, unknown> ? {
        [K in string & keyof T as AsCamelCase<K>]: CamelCaseKeysRecord<T[K]>;
    } & {
        [K in Exclude<keyof T, string>]: CamelCaseKeysRecord<T[K]>;
    } : T;
    
    function toCamelCaseKeys<T>(val: T): CamelCaseKeysRecord<T> {
        if (Array.isArray(val)) {
            return val.map(toCamelCaseKeys) as unknown as CamelCaseKeysRecord<T>;
        }
        if (typeof val === 'object') {
            return Object.fromEntries(Object
                .entries(val)
                .map(([k, v]) => [
                    k.replace(/_+(.)/g, (_, g) => g.toUpperCase()),
                    toCamelCaseKeys(v as Record<string, unknown>),
                ])) as CamelCaseKeysRecord<T>;
        }
        return val as unknown as CamelCaseKeysRecord<T>;
    }

    https://www.typescriptlang.org/play?target=7&ts=4....
    Ответ написан
    6 комментариев
  • Как при рекурсивном переборе древовидных объектов вызывать fetch на каждый item и на выходе получать измененный массив?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    const addingOptions = arr => Promise.all(arr.map(
        item => Promise.all([
            fetchOptions(item.id),
            item.children.length ? addingOptions(item.children) : []
        ]).then(([options, children]) => ({
            ...item,
            options,
            children
        }))
    ));
    Ответ написан
    Комментировать
  • Почему JS решил задачу на рекурсию гораздо быстрее Python/Lua?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    Синтетические бенчмарки врут практически всегда, потому что те кто их пишет редко знает досконально все сравниваемые технологии и вряд ли сможет свести задачу к схожим условиям. Как правило, схожие условия выходят только при отключении всех возможных оптимизаций, ибо оптимизации у разных технологий работают по разному.
    Как уже написали выше, Вы зря не превели код на Python, возможно специалисты по этому ЯП предложили бы более оптимальное решение.
    По js варианту могу сказать, что v8 очень хорошо умеет оптимизировать хвостовую рекурсию. И в данном примере вместо дорогой рекурсии у Вас будет работать более дешевый цикл. Я могу Вас удивить, перепишите свое решение на C вот прямо как есть и скомпилируйте без оптимизаций - js + v8 окажется быстрее
    Ответ написан
    Комментировать
  • JavaScript (рекурсия) Как из одного массива (каталог) сделать другой (дерево)?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    function parsePath(path) {
      return path.split(',').reduce((acc, item) => {
        const [key, value] = item.split('=');
        switch(key) {
        case 'name':
          acc.name = value;
          break;
        case 'f':
        case 'g':
          acc[key].push(value);
          break;
        }
        return acc;
      }, {
        name: '',
        f: [],
        g: []
      });
    }
    
    function normalizeTree(tree) {
      return Object.keys(tree).map(label => {
        const item = tree[label];
        if(item.id) { return item; }
        const children = normalizeTree(item);
        const id = `[${children.map(({id}) => id).join(',')}]`;
        return {id, label, children};
      });
    }
    
    function reduceToTree(data) {
      return normalizeTree(data.reduce((acc, {path, id}) => {
        const {name, f, g} = parsePath(path);
        const target = f.reverse().concat(name).reduce((target, label) => {
          return target[label] || (target[label] = {});
        }, acc);
        target.id = id;
        target.label = name;
        target.g = g;
        return acc;
      }, {}));
    }
    
    console.log(reduceToTree([
      {
        "path": "name=Tel6,g=tovarov,g=catalog",
        "id": "6000",
        "name": "Tel6"
      },
      {
        "path": "name=Tel1,f=Samsung,g=tovarov,g=catalog", // f= неограниченная вложенность
        "id": "1000",
        "name": "Tel1"
      },
      {
        "path": "name=Tel2,f=Samsung,g=tovarov,g=catalog", // f= неограниченная вложенность
        "id": "2000",
        "name": "Tel2"
      },
      {
        "path": "name=Tel3,f=Galaxy,f=Samsung,g=tovarov,g=catalog", // f= неограниченная вложенность
        "id": "3000",
        "name": "Tel3"
      },
      {
        "path": "name=Tel4,f=A,f=Samsung,g=tovarov,g=catalog", // f= неограниченная вложенность
        "id": "4000",
        "name": "Tel4"
      },
      {
        "path": "name=Tel5,f=A,f=Samsung,g=tovarov,g=catalog", // f= неограниченная вложенность
        "id": "5000",
        "name": "Tel5"
      }
      // ...
    ]));
    Ответ написан
  • Как написать асинхронную рекурсивную функцию?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    function recursiveRequest(requestData) {
      return fetch(
        //здесь формируем запрос из requestData
      ).then(response => response.json()).then(result => {
        if(result.isFinal) return result; // тут условие
        return recursiveRequest(result.nextRequest); //вызываем следующий запрос
      });
    }
    
    recursiveRequest({}).then(finalResult => {
      //работаем с последним результатом
    });
    Ответ написан
    Комментировать
  • Рекурсивное каррирование?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    Вся проблема в том, что Вы на каждый вызов переопределяете метод valueOf у оригинальной функции, правильнее возвращать каждый раз новую функцию:
    const curring = (...initArgs) => {
      let sum = 0;
      const curried = (...args) => {
        sum = args.reduce((a, b) => a + b, sum);
        return curried;
      };
      curried.valueOf = () => sum;
      return curried(...initArgs);
    };
    Ответ написан
    Комментировать
  • Как функция получает доступ к себе при рекурсивном вызове?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    в текущей области видимости 'func' не объявлена

    как раз таки объявлена. В любой именованной функции ее имя создается в момент вызова (наравне с arguments и this) и ссылается на саму функцию. Наиболее наглядно это показывают именованные функциональные выражения:
    var f = function func() {
      console.log(func.name); // 'func'
    };
    console.log(f.name); // 'func'
    console.log(func.name); // Reference error так как func нет в этой области видимости
    Ответ написан
    Комментировать
  • Как создать вечный процесс на node.js?

    bingo347
    @bingo347 Куратор тега Node.js
    Crazy on performance...
    Насчет setInterval уже подсказал Александр Вульф
    От себя добавлю еще совет ознакомится с такой утилитой как pm2
    Ответ написан
    Комментировать