В данном домашнем задании вам необходимо реализовать функции, представленные ниже.
Для обработки ошибок, встречающихся при реализации, необходимо воспользоваться синтаксисом
throw new Error(<код ошибки из задания>)
. Подробнее можно прочесть здесь.
Для запуска всех тестов выполняйте команду:
yarn test
Для запуска теста отдельной функции:
yarn test:single <название функции>
Например:
yarn test:single sum
Реализуйте функцию sum, которая принимает произвольное количество аргументов и возвращает их сумму.
Ошибки, которые должны быть обработаны:
- Не переданы хотя бы два аргумента. Код ошибки
INVALID_ARGUMENTS_COUNT
. - Хотя бы один из аргументов не типа
number
. Код ошибкиINVALID_ARGUMENT
.
Примеры использования:
sum(1, 2, 3); // 6
sum(); // ошибка с кодом INVALID_ARGUMENTS_COUNT
sum(0, 1, '1', 2); // ошибка с кодом INVALID_ARGUMENT
Реализуйте функцию pow, которая возвращает возведенное в степень число и имеет два формата вызова - pow(base, exponent)
и pow(base)(exponent)
.
Ошибки, которые должны быть обработаны:
- Хотя бы один из аргументов не типа
number
. Код ошибкиINVALID_ARGUMENT
.
Примеры использования:
pow(2, 2); // 4
pow(2)(2); // 4
pow(2)('2'); // ошибка с кодом INVALID_ARGUMENT
Реализуйте функцию intersection, которая принимает два массива чисел и возвращает массив чисел, присутствующих в первом и во втором массивах.
Ошибки, которые должны быть обработаны:
- Не переданы два аргумента. Код ошибки
INVALID_ARGUMENTS_COUNT
. - Хотя бы один из аргументов функции не массив. Код ошибки
INVALID_ARGUMENT
. - Хотя бы один из элементов массива не типа
number
. Код ошибкиINVALID_ELEMENT_IN_ARRAY
.
Примеры использования:
intersection([1], [2]); // []
intersection([1, 2], [3, 2, 1]); // [1, 2]
intersection([1, 1], [1, 1]); // [1]
intersection([1, 2, 1], [1]); // [1]
intersection([], []); // []
intersection() // ошибка с кодом INVALID_ARGUMENTS_COUNT
intersection([], '[]') // ошибка с кодом INVALID_ARGUMENT
intersection([], [1, '2']) // ошибка с кодом INVALID_ELEMENT_IN_ARRAY
Реализуйте функцию sort, которая принимает строку, состоящую из слов, разделенных пробелами. В каждом слове предложения она сортирует буквы в порядке кодовых точек Unicode, а слова по количеству букв в них, и возвращает результат в виде строки. Если в слове попадается буква в верхнем регистре, она должна быть приведена к нижнему.
Ошибки, которые должны быть обработаны:
- Переданный аргумент не типа
string
. Код ошибкиINVALID_ARGUMENT
.
Примеры использования:
sort('hello world'); // 'ehllo dlorw'
sort('привет школа Metaclass'); // 'аклош веипрт aacelmsst'
sort('1234 111'); // '111 1234'
sort(11); // ошибка с кодом INVALID_ARGUMENT
Реализуйте функцию removeAnagrams, которая принимает массив строк и удаляет из данного массива строки, являющиеся анаграммами.
Ошибки, которые должны быть обработаны:
- Переданный аргумент не массив. Код ошибки
INVALID_ARGUMENT
. - В переданном массиве хотя бы один элемент не типа
string
. Код ошибкиINVALID_ELEMENT_IN_ARRAY
.
Примеры использования:
removeAnagrams(['cat', 'act', 'arc']); // ['arc']
removeAnagrams(['car', 'arc']); // []
removeAnagrams('str'); // ошибка с кодом INVALID_ARGUMENT
removeAnagrams(['str', 5]); // ошибка с кодом INVALID_ELEMENT_IN_ARRAY
Реализуйте функцию patchArrays, которая для всех массивов добавляет следующие методы:
- Метод
count
возвращает длину массива. - Метод
insert
осуществляет вставку элемента в массив по индексу и возвращает измененный данный массив. В случае отрицательного индекса, элемент становится первым. Если индекс > длинны массива, элемент становится последним. - Метод
remove
удаляет из массива первый встречающийся элемент с таким значением и возвращает измененный данный массив. Если такого элемента в массиве нет, он возвращает неизмененный данный массив.
Ошибки, которые должны быть обработаны:
- Первый аргумент метода
insert
не типаnumber
. Код ошибкиINVALID_ARGUMENT
.
Примеры использования:
[1, 2, 3].count(); // 3
[].count(); // 0
const arr = [];
arr.insert(10, 1); // [1]
arr.insert(1, 'name'); // [1, 'name']
arr.insert(1, null); // [1, null, 'name']
arr.insert(0, null); // [null, 1, null, 'name']
arr.remove(2); // [null, 1, null, 'name']
arr.remove(1); // [null, null, 'name']
arr.remove('name'); // [null, null]
arr.remove(null); // [null]
arr.remove(null).insert('2'); // ['2']
[].insert('0', null) // ошибка с кодом INVALID_ARGUMENT
Реализуйте функцию multiply.
Ошибки, которые должны быть обработаны:
- Один из аргументов не типа
number
. Код ошибкиINVALID_ARGUMENT
.
Примеры использования:
const multiplyByTen = multiply(10);
multiplyByTen(2); // 20
const multiplyByTwo = multiply(2);
multiplyByTwo(3); // 6
const multiplyByTwo = multiply(["two"]); ошибка с кодом INVALID_ARGUMENT
const multiplyByTwo = multiply(2);
multiplyByTwo('3'); // ошибка с кодом INVALID_ARGUMENT
Реализуйте функцию getNumberProps, которая принимает в качестве аргумента объект, свойствами которого могут быть другие объекты с неограниченным уровнем вложенности, и возвращает отсортированный массив названий всех численных свойств исходного и вложенных объектов.
Ошибки, которые должны быть обработаны:
- Переданный аргумент не объект. Код ошибки
INVALID_ARGUMENT
.
Примеры использования:
getNumberProps({ a: 1, c: 1, b: { c: 2, d: 1, e: '1' }, m: 3 }); // ['a', 'c', 'c', 'd', 'm']
getNumberProps('{ a: 1, b: { e: 4}}') ошибка с кодом INVALID_ARGUMENT
9. Обход дерева в глубину (dfs)
Реализуйте функцию dfs, которая принимает в качестве аргумента объект, отражающий небинарное дерево(узел может иметь больше двух потомков) и возвращает массив узлов, соответствующий обходу в глубину. Обход осуществляется слева направо (по возрастанию индекса в массиве).
Пример графа: A / \ B C / \ / \ D E F G Этот же граф в виде объекта: const graph = { A: ['B', 'C'], B: ['D', 'E'], C: ['F', 'G'], D: [], E: [], F: [], G: [], };
Ошибки, которые должны быть обработаны:
- Переданный аргумент не объект. Код ошибки
INVALID_ARGUMENT
.
Примеры использования:
dfs(graph) // ['A', 'B', 'D', 'E', 'C', 'F', 'G']
dfs('{}') // ошибка с кодом INVALID_ARGUMENT
10. Обход дерева в ширину (bfs)
Реализуйте функцию bfs, которая принимает в качестве аргумента объект, отражающий небинарное дерево(узел может иметь больше двух потомков) и возвращает массив узлов, соответствующий обходу в ширину. Обход осуществляется слева направо(по возрастанию индекса в массиве).
Пример графа: A / \ B C / \ / \ D E F G Этот же граф в виде объекта: const graph = { A: ['B', 'C'], B: ['D', 'E'], C: ['F', 'G'], D: [], E: [], F: [], G: [], };
Ошибки, которые должны быть обработаны:
- Переданный аргумент не объект. Код ошибки
INVALID_ARGUMENT
.
Примеры использования:
bfs(graph) // ['A', 'B', 'С', 'D', 'E', 'F', 'G']
bfs('{}') // ошибка с кодом INVALID_ARGUMENT
Реализуйте функцию planEvent, которая планирует вызов функции cb
через некоторое время(timeout
) и возвращает Promise
с результатом выполнения функции cb
.
В случае timeout
<= 0 вызов должен произойти сразу же.
Подробнее о Promise
и async/await
можно прочесть здесь.
Ошибки, которые должны быть обработаны:
- Первый аргумент не типа
function
. Код ошибкиINVALID_ARGUMENT
. - Второй аргумент не типа
number
. Код ошибкиINVALID_ARGUMENT
.
Примеры использования:
const f = () => 'Done';
const result = await planEvent(f, 3000);
//Через 3 секунды
console.log(result); // 'Done'
const result = await planEvent('str', 3000); // ошибка с кодом INVALID_ARGUMENT
const result = await planEvent(() => 'Done', '3000'); // ошибка с кодом INVALID_ARGUMENT
Напишите функцию promiseFrame. Функция принимает первым аргументом массив асинхронных функций, не принимающих аргументов и возвращающих некоторые результаты (не void
), вторым необязательным аргументом — максимальное количество промисов, которое может выполняться одновременно. Согласно заданному лимиту на одновременное выполнение, функция параллельно обрабатывает переданные асинхронные функции и возвращает Promise
, удовлетворяющийся с массивом результатов выполнения функций в порядке, в котором были переданы функции (но не в порядке их выполнения). В случае, если лимит на одновременное выполнение промисов не передан, ограничение накладываться не должно и функция должна вести себя аналогично Promise.all
. Если хотя бы одна асинхронная функция выкидывает ошибку, promiseFrame
должен выбросить ту же ошибку и только её. Обратите внимание, что ограничение на количество одновременных выполнений не означает разделение функций на подмножества и порционное их выполнение: если имеются ещё не выполненные функции и лимит на одновременное их выполнение не исчерпан, следующая по порядку функция должна выполняться. Заметьте, что переданные функции могут быть и синхронными — в таком случае в результаты выполнения должен попасть просто результат вызова такой функции, при этом из функции promiseFrame
необходимо также вернуть Promise
.
Ошибки, которые должны быть обработаны:
- Первый аргумент не массив. Код ошибки
INVALID_ARGUMENT
. - Второй аргумент не типа
number
или число не больше нуля. Код ошибкиINVALID_ARGUMENT
.
Примеры использования:
// getValueAfterTime — гипотетическая функция, возвращающая значение из первого аргумента
// спустя время в миллисекундах, переданное во втором аргументе
const asyncFunc1 = async () => await getValueAfterTime(1, 2000)
const asyncFunc2 = async () => await getValueAfterTime('a', 500);
const syncFunc = () => 3
const results = await promiseFrame([asyncFunc1, asyncFunc2, syncFunc], 2);
// Через 2 секунды
console.log(results); // [1, 'a', 3]
const results = await promiseFrame('str'); // ошибка с кодом INVALID_ARGUMENT
const results = await promiseFrame([() => 'a'], -1); // ошибка с кодом INVALID_ARGUMENT
Напишите функцию-декоратор memo. Функция-декоратор принимает первым аргументом чистую оригинальную функцию (с аргументами или без), возвращающую некоторое значение, вторым необязательным аргументом — время в миллисекундах, означающее время, в течение которого нужно мемоизировать возвращаемое значение оригинальной функции, исходя из её аргументов. Непереданный второй аргумент означает бесконечную мемоизацию. Функция-декоратор возвращает новую функцию, принимающую те же аргументы, что оригинальная и возвращающая такие же значения, как оригинальная функция при совпадающих аргументах. Обратите внимание, что мемоизация распространяется на каждый отдельный набор аргументов, то есть применение одних аргументов не сбрасывает мемоизацию результата функции при других аргументах. Кроме того, в случае ещё не истёкшей мемоизации по определённым аргументам вызов мемоизированной функции обновляет срок истечения мемоизации по этим аргументам. Для сравнения каждого из аргументов используйте shallow-сравнение, то есть в случае сравнения объектов, массивов или функций используйте сравнение по ссылке.
Ошибки, которые должны быть обработаны:
- Первый аргумент не функция. Код ошибки
INVALID_ARGUMENT
. - Второй аргумент не типа
number
или число меньше нуля. Код ошибкиINVALID_ARGUMENT
.
Примеры использования:
// Предположим, в функции original — сложные вычисления
const original = (n) => n
const memoized = memo(original, 1000);
console.log(original(1))
console.log(original(1))
console.log(original(2))
// На данный момент original была вызвана лишь по одному разу с аргументами 1 и 2
// Через 1 секунду
console.log(original(1))
console.log(original(2))
// Теперь original была вызвана лишь по два раза с аргументами 1 и 2
const memoized = memo('str'); // ошибка с кодом INVALID_ARGUMENT
const memoized = memo(() => 1, -1); // ошибка с кодом INVALID_ARGUMENT
- Укажите личный ключ
user_token
в файлеconfig.yml
Примерconfig.yml
:
user_token: e3631261-c636-42458-ab0b-g8e534e984ee
- Выполните команду запуска тестов
yarn test
- При успешном прохождении тестов, отправьте изменения в свой репозиторий