{"id":21611718,"url":"https://github.com/ktsstudio/frontend-hw-1","last_synced_at":"2025-07-20T07:05:21.608Z","repository":{"id":86391403,"uuid":"512143354","full_name":"ktsstudio/frontend-hw-1","owner":"ktsstudio","description":null,"archived":false,"fork":false,"pushed_at":"2024-04-03T18:17:25.000Z","size":126,"stargazers_count":3,"open_issues_count":1,"forks_count":2,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-06-26T23:21:19.761Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ktsstudio.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-07-09T09:18:10.000Z","updated_at":"2025-04-17T16:22:46.000Z","dependencies_parsed_at":"2025-03-28T22:29:04.768Z","dependency_job_id":"dbd79f86-327d-41e1-9abd-8048f114c812","html_url":"https://github.com/ktsstudio/frontend-hw-1","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/ktsstudio/frontend-hw-1","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ktsstudio%2Ffrontend-hw-1","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ktsstudio%2Ffrontend-hw-1/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ktsstudio%2Ffrontend-hw-1/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ktsstudio%2Ffrontend-hw-1/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ktsstudio","download_url":"https://codeload.github.com/ktsstudio/frontend-hw-1/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ktsstudio%2Ffrontend-hw-1/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":266081240,"owners_count":23873511,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-24T21:13:39.218Z","updated_at":"2025-07-20T07:05:21.557Z","avatar_url":"https://github.com/ktsstudio.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Начинающий React разработчик. Домашнее задание №1\n\nВ данном домашнем задании вам необходимо реализовать функции, представленные ниже.\nДля обработки ошибок, встречающихся при реализации, необходимо воспользоваться синтаксисом\n`throw new Error(\u003cкод ошибки из задания\u003e)`. Подробнее можно прочесть [здесь](https://learn.javascript.ru/try-catch).\n\n## Запуск тестов\n\nДля запуска **всех тестов** выполняйте команду:\n\n```\nyarn test\n```\n\nДля запуска теста **отдельной функции**:\n\n```\nyarn test:single \u003cназвание функции\u003e\n```\n\nНапример:\n\n```\nyarn test:single sum\n```\n\n## 1. Суммирование аргументов\nРеализуйте функцию [sum](src/sum.ts), которая принимает произвольное количество аргументов и возвращает их сумму.\n\n**Ошибки, которые должны быть обработаны:**\n1) Не переданы хотя бы два аргумента. Код ошибки `INVALID_ARGUMENTS_COUNT`.\n2) Хотя бы один из аргументов не типа `number`. Код ошибки `INVALID_ARGUMENT`.\n\n**Примеры использования:**\n1) `sum(1, 2, 3);        // 6`\n2) `sum();               // ошибка с кодом INVALID_ARGUMENTS_COUNT`\n3) `sum(0, 1, '1', 2); // ошибка с кодом INVALID_ARGUMENT`\n\n## 2. Возведение в степень\nРеализуйте функцию [pow](src/pow.ts), которая возвращает возведенное в степень число и имеет два формата вызова - `pow(base, exponent)` и `pow(base)(exponent)`.\n\n**Ошибки, которые должны быть обработаны:**\n1) Хотя бы один из аргументов не типа `number`. Код ошибки `INVALID_ARGUMENT`.\n\n**Примеры использования:**\n1) `pow(2, 2);        // 4`\n2) `pow(2)(2);        // 4`\n3) `pow(2)('2'); // ошибка с кодом INVALID_ARGUMENT`\n\n## 3. Пересечение двух массивов\nРеализуйте функцию [intersection](src/intersection.ts), которая принимает два массива чисел и возвращает массив чисел, присутствующих в первом и во втором массивах.\n\n**Ошибки, которые должны быть обработаны:**\n1) Не переданы два аргумента. Код ошибки `INVALID_ARGUMENTS_COUNT`.\n2) Хотя бы один из аргументов функции не массив. Код ошибки `INVALID_ARGUMENT`.\n3) Хотя бы один из элементов массива не типа `number`. Код ошибки `INVALID_ELEMENT_IN_ARRAY`.\n\n**Примеры использования:**\n1) `intersection([1], [2]);            // []`\n2) `intersection([1, 2], [3, 2, 1]);   // [1, 2]`\n3) `intersection([1, 1], [1, 1]);      // [1]`\n4) `intersection([1, 2, 1], [1]);      // [1]`\n5) `intersection([], []);              // []`\n6) `intersection()                     // ошибка с кодом INVALID_ARGUMENTS_COUNT`\n7) `intersection([], '[]')             // ошибка с кодом INVALID_ARGUMENT`\n8) `intersection([], [1, '2'])         // ошибка с кодом INVALID_ELEMENT_IN_ARRAY`\n\n## 4. Сортировка строк\nРеализуйте функцию [sort](src/sort.ts), которая принимает строку, состоящую из слов, разделенных пробелами.\nВ каждом слове предложения она сортирует буквы в порядке кодовых точек Unicode, а слова по количеству букв в них,\nи возвращает результат в виде строки.\nЕсли в слове попадается буква в верхнем регистре, она должна быть приведена к нижнему.\n\n**Ошибки, которые должны быть обработаны:**\n1) Переданный аргумент не типа `string`. Код ошибки `INVALID_ARGUMENT`.\n\n**Примеры использования:**\n1) `sort('hello world');            // 'ehllo dlorw'`\n2) `sort('привет школа Metaclass'); // 'аклош веипрт aacelmsst'`\n3) `sort('1234 111');               // '111 1234'`\n4) `sort(11);                       // ошибка с кодом INVALID_ARGUMENT`\n\n## 5. Фильтрация не анаграмм\nРеализуйте функцию [removeAnagrams](src/removeAnagrams.ts), которая принимает массив строк и удаляет из данного массива строки, являющиеся анаграммами.\n\n**Ошибки, которые должны быть обработаны:**\n1) Переданный аргумент не массив. Код ошибки `INVALID_ARGUMENT`.\n2) В переданном массиве хотя бы один элемент не типа `string`. Код ошибки `INVALID_ELEMENT_IN_ARRAY`.\n\n**Примеры использования:**\n1) `removeAnagrams(['cat', 'act', 'arc']);  // ['arc']`\n2) `removeAnagrams(['car', 'arc']);         // []`\n3) `removeAnagrams('str');                  // ошибка с кодом INVALID_ARGUMENT`\n4) `removeAnagrams(['str', 5]);             // ошибка с кодом INVALID_ELEMENT_IN_ARRAY`\n\n## 6. Дополнительные методы массива\nРеализуйте функцию [patchArrays](src/patchArrays.ts), которая для всех массивов добавляет следующие методы:\n1) Метод `count` возвращает длину массива.\n2) Метод `insert` осуществляет вставку элемента в массив по индексу и возвращает измененный данный массив. В случае отрицательного индекса, элемент становится первым. Если индекс \u003e длинны массива, элемент становится последним.\n3) Метод `remove` удаляет из массива первый встречающийся элемент с таким значением и возвращает измененный данный массив. Если такого элемента в массиве нет, он возвращает неизмененный данный массив.\n\n[Подсказка](https://learn.javascript.ru/native-prototypes)\n\n**Ошибки, которые должны быть обработаны:**\n1) Первый аргумент метода `insert` не типа `number`. Код ошибки `INVALID_ARGUMENT`.\n\n**Примеры использования:**\n1) `[1, 2, 3].count();    // 3`\n2) `[].count();           // 0`\n3) `const arr = [];`\u003cbr/\u003e\n    `arr.insert(10, 1);     // [1]`\u003cbr/\u003e\n    `arr.insert(1, 'name'); // [1, 'name']`\u003cbr/\u003e\n    `arr.insert(1, null);   // [1, null, 'name']`\u003cbr/\u003e\n    `arr.insert(0, null);   // [null, 1, null, 'name']`\u003cbr/\u003e\n    `arr.remove(2);         // [null, 1, null, 'name']`\u003cbr/\u003e\n    `arr.remove(1);         // [null, null, 'name']`\u003cbr/\u003e\n    `arr.remove('name');    // [null, null]`\u003cbr/\u003e\n    `arr.remove(null);      // [null]`\u003cbr/\u003e\n    `arr.remove(null).insert('2');      // ['2']`\n4) `[].insert('0', null) // ошибка с кодом INVALID_ARGUMENT`\n\n## 7. Умножение с частичным применением\nРеализуйте функцию [multiply](src/multiply.ts).\n\n**Ошибки, которые должны быть обработаны:**\n1) Один из аргументов не типа `number`. Код ошибки `INVALID_ARGUMENT`.\n\n**Примеры использования:**\n1) `const multiplyByTen = multiply(10);`\u003cbr/\u003e\n   `multiplyByTen(2);   // 20`\n2) `const multiplyByTwo = multiply(2);`\u003cbr/\u003e\n   `multiplyByTwo(3);   // 6`\n3) `const multiplyByTwo = multiply([\"two\"]); ошибка с кодом INVALID_ARGUMENT`\n4) `const multiplyByTwo = multiply(2);`\u003cbr/\u003e\n   `multiplyByTwo('3');   // ошибка с кодом INVALID_ARGUMENT`\n\n## 8. Получение численных свойств\nРеализуйте функцию [getNumberProps](src/getNumberProps.ts), которая принимает в качестве аргумента объект, свойствами которого могут быть\nдругие объекты с неограниченным уровнем вложенности, и возвращает отсортированный массив названий всех численных свойств\nисходного и вложенных объектов.\n\n**Ошибки, которые должны быть обработаны:**\n1) Переданный аргумент не объект. Код ошибки `INVALID_ARGUMENT`.\n\n**Примеры использования:**\n1) `getNumberProps({ a: 1, c: 1, b: { c: 2, d: 1, e: '1' }, m: 3 }); // ['a', 'c', 'c', 'd', 'm']`\n2) `getNumberProps('{ a: 1, b: { e: 4}}') ошибка с кодом INVALID_ARGUMENT`\n\n## 9. Обход дерева в глубину ([dfs](https://en.wikipedia.org/wiki/Depth-first_search))\nРеализуйте функцию [dfs](src/dfs.ts), которая принимает в качестве аргумента объект, отражающий небинарное дерево(узел может иметь больше двух потомков) и возвращает массив узлов, соответствующий обходу в глубину.\nОбход осуществляется слева направо (по возрастанию индекса в массиве).\n\u003cpre\u003e\nПример графа:\n            A \n          /   \\ \n         B     C \n        /  \\   / \\ \n       D    E F   G\n\nЭтот же граф в виде объекта:\nconst graph = {\n    A: ['B', 'C'],\n    B: ['D', 'E'],\n    C: ['F', 'G'],\n    D: [],\n    E: [],\n    F: [],\n    G: [],\n};\n\u003c/pre\u003e\n\n**Ошибки, которые должны быть обработаны:**\n1) Переданный аргумент не объект. Код ошибки `INVALID_ARGUMENT`.\n\n**Примеры использования:**\n1) `dfs(graph) // ['A', 'B', 'D', 'E', 'C', 'F', 'G']`\n2) `dfs('{}') // ошибка с кодом INVALID_ARGUMENT`\n\n## 10. Обход дерева в ширину ([bfs](https://en.wikipedia.org/wiki/Breadth-first_search))\nРеализуйте функцию [bfs](src/bfs.ts), которая принимает в качестве аргумента объект, отражающий небинарное дерево(узел может иметь больше двух потомков) и возвращает массив узлов, соответствующий обходу в ширину.\nОбход осуществляется слева направо(по возрастанию индекса в массиве).\n\u003cpre\u003e\nПример графа:\n            A \n          /   \\ \n         B     C \n        /  \\   / \\ \n       D    E F   G\n\nЭтот же граф в виде объекта:\nconst graph = {\n    A: ['B', 'C'],\n    B: ['D', 'E'],\n    C: ['F', 'G'],\n    D: [],\n    E: [],\n    F: [],\n    G: [],\n};\n\u003c/pre\u003e\n\n**Ошибки, которые должны быть обработаны:**\n1) Переданный аргумент не объект. Код ошибки `INVALID_ARGUMENT`.\n\n**Примеры использования:**\n1) `bfs(graph) // ['A', 'B', 'С', 'D', 'E', 'F', 'G']`\n2) `bfs('{}') // ошибка с кодом INVALID_ARGUMENT`\n\n## 11. Асинхронное выполнение функции\nРеализуйте функцию [planEvent](src/planEvent.ts), которая планирует вызов функции `cb` через некоторое время(`timeout`) и возвращает `Promise` с результатом выполнения функции `cb`.\nВ случае `timeout` \u003c= 0 вызов должен произойти сразу же.\nПодробнее о `Promise` и `async/await` можно прочесть [здесь](https://learn.javascript.ru/async). \n\n**Ошибки, которые должны быть обработаны:**\n1) Первый аргумент не типа `function`. Код ошибки `INVALID_ARGUMENT`.\n1) Второй аргумент не типа `number`. Код ошибки `INVALID_ARGUMENT`.\n\n**Примеры использования:**\n1) `const f = () =\u003e 'Done';`\u003cbr/\u003e\n`const result = await planEvent(f, 3000);`\u003cbr/\u003e\n`//Через 3 секунды`\u003cbr/\u003e\n`console.log(result); // 'Done'`\n2) `const result = await planEvent('str', 3000); // ошибка с кодом INVALID_ARGUMENT`\n2) `const result = await planEvent(() =\u003e 'Done', '3000'); // ошибка с кодом INVALID_ARGUMENT`\n\n## 12. Ограничение на одновременное выполнение\nНапишите функцию [promiseFrame](src/promiseFrame.ts). Функция принимает первым аргументом массив асинхронных функций, не принимающих аргументов и возвращающих некоторые результаты (не `void`), вторым необязательным аргументом — максимальное количество промисов, которое может выполняться одновременно. Согласно заданному лимиту на одновременное выполнение, функция параллельно обрабатывает переданные асинхронные функции и возвращает `Promise`, удовлетворяющийся с массивом результатов выполнения функций в порядке, в котором были переданы функции (но не в порядке их выполнения). В случае, если лимит на одновременное выполнение промисов не передан, ограничение накладываться не должно и функция должна вести себя аналогично [`Promise.all`](https://learn.javascript.ru/promise-api#promise-all). Если хотя бы одна асинхронная функция выкидывает ошибку, `promiseFrame` должен выбросить ту же ошибку и только её. Обратите внимание, что ограничение на количество одновременных выполнений не означает разделение функций на подмножества и порционное их выполнение: если имеются ещё не выполненные функции и лимит на одновременное их выполнение не исчерпан, следующая по порядку функция должна выполняться. Заметьте, что переданные функции могут быть и синхронными — в таком случае в результаты выполнения должен попасть просто результат вызова такой функции, при этом из функции `promiseFrame` необходимо также вернуть `Promise`.\n\n**Ошибки, которые должны быть обработаны:**\n1) Первый аргумент не массив. Код ошибки `INVALID_ARGUMENT`.\n2) Второй аргумент не типа `number` или число не больше нуля. Код ошибки `INVALID_ARGUMENT`.\n\n**Примеры использования:**\n1) `// getValueAfterTime — гипотетическая функция, возвращающая значение из первого аргумента`\u003cbr/\u003e\n`// спустя время в миллисекундах, переданное во втором аргументе`\u003cbr/\u003e\n`const asyncFunc1 = async () =\u003e await getValueAfterTime(1, 2000)`\u003cbr/\u003e\n`const asyncFunc2 = async () =\u003e await getValueAfterTime('a', 500);`\u003cbr/\u003e\n`const syncFunc = () =\u003e 3`\u003cbr/\u003e\n`const results = await promiseFrame([asyncFunc1, asyncFunc2, syncFunc], 2);`\u003cbr/\u003e\n`// Через 2 секунды`\u003cbr/\u003e\n`console.log(results); // [1, 'a', 3]`\n2) `const results = await promiseFrame('str'); // ошибка с кодом INVALID_ARGUMENT`\n3) `const results = await promiseFrame([() =\u003e 'a'], -1); // ошибка с кодом INVALID_ARGUMENT`\n\n\n## 13. Временная мемоизация\nНапишите функцию-декоратор [memo](src/memo.ts). Функция-декоратор принимает первым аргументом чистую оригинальную функцию (с аргументами или без), возвращающую некоторое значение, вторым необязательным аргументом — время в миллисекундах, означающее время, в течение которого нужно мемоизировать возвращаемое значение оригинальной функции, исходя из её аргументов. Непереданный второй аргумент означает бесконечную мемоизацию. Функция-декоратор возвращает новую функцию, принимающую те же аргументы, что оригинальная и возвращающая такие же значения, как оригинальная функция при совпадающих аргументах. Обратите внимание, что мемоизация распространяется на каждый отдельный набор аргументов, то есть применение одних аргументов не сбрасывает мемоизацию результата функции при других аргументах. Кроме того, в случае ещё не истёкшей мемоизации по определённым аргументам вызов мемоизированной функции обновляет срок истечения мемоизации по этим аргументам. Для сравнения каждого из аргументов используйте shallow-сравнение, то есть в случае сравнения объектов, массивов или функций используйте сравнение по ссылке.\n\n**Ошибки, которые должны быть обработаны:**\n1) Первый аргумент не функция. Код ошибки `INVALID_ARGUMENT`.\n2) Второй аргумент не типа `number` или число меньше нуля. Код ошибки `INVALID_ARGUMENT`.\n\n**Примеры использования:**\n1)\t`// Предположим, в функции original — сложные вычисления` \u003cbr /\u003e\n      `const original = (n) =\u003e n`\u003cbr/\u003e\n      `const memoized = memo(original, 1000);`\u003cbr/\u003e\n      `console.log(original(1))`\u003cbr /\u003e\n      `console.log(original(1))`\u003cbr /\u003e\n      `console.log(original(2))`\u003cbr /\u003e\n      `// На данный момент original была вызвана лишь по одному разу с аргументами 1 и 2`\u003cbr /\u003e\n      `// Через 1 секунду`\u003cbr/\u003e\n      `console.log(original(1))`\u003cbr /\u003e\n      `console.log(original(2))`\u003cbr /\u003e\n      `// Теперь original была вызвана лишь по два раза с аргументами 1 и 2`\u003cbr /\u003e\n2) `const memoized = memo('str'); // ошибка с кодом INVALID_ARGUMENT`\n3) `const memoized = memo(() =\u003e 1, -1); // ошибка с кодом INVALID_ARGUMENT`\n\n## Перед отправкой ДЗ на проверку\n\n1. Укажите личный ключ `user_token` в файле `config.yml`\n   Пример `config.yml`:\n\n```\nuser_token: e3631261-c636-42458-ab0b-g8e534e984ee\n```\n\n2. Выполните команду запуска тестов\n\n```\nyarn test\n```\n\n3. При успешном прохождении тестов, отправьте изменения в свой репозиторий\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fktsstudio%2Ffrontend-hw-1","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fktsstudio%2Ffrontend-hw-1","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fktsstudio%2Ffrontend-hw-1/lists"}