Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Week 2 #447

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
77 changes: 77 additions & 0 deletions projects/array-objects/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
/* ДЗ 2 - работа с массивами и объектами */

/*
Задание 1:

Напишите аналог встроенного метода forEach для работы с массивами.
Посмотрите как работает forEach и повторите это поведение для массива, который будет передан в параметре array

Пример:
forEach([1, 2, 3], (el) => console.log(el)); // выведет каждый элемент массива
*/
function forEach(array, fn) {
for (const [ix, el] of array.entries()) {
fn (el, ix, array)
}
}

/*
Задание 2:

Напишите аналог встроенного метода map для работы с массивами.
Посмотрите как работает map и повторите это поведение для массива, который будет передан в параметре array

Пример:
const newArray = map([1, 2, 3], (el) => el ** 2);
console.log(newArray); // выведет [1, 4, 9]
*/
function map(array, fn) {
const newArray = [];

for (const [ix, el] of array.entries()) {
newArray.push(fn(el, ix, array));
}

return newArray;
}

/*
Задание 3:

Напишите аналог встроенного метода reduce для работы с массивами.
Посмотрите как работает reduce и повторите это поведение для массива, который будет передан в параметре array

Пример:
const sum = reduce([1, 2, 3], (all, current) => all + current);
console.log(sum); // выведет 6
*/
function reduce(array, fn, initial) {
let startIndex = 0;
let all = initial;

if (initial = undefined) {
startIndex = 1;
all = array[0];
}

for (let i = startIndex; i < array.length; i++) {
all = fn(all, array[i], i, array)
}

return all;
}

/*
Задание 4:

Функция должна перебрать все свойства объекта, преобразовать их имена в верхний регистр и вернуть в виде массива

Пример:
const keys = upperProps({ name: 'Сергей', lastName: 'Петров' });
console.log(keys) // выведет ['NAME', 'LASTNAME']
*/
function upperProps(obj) {
return Object.keys(obj).map(k => k.toUpperCase())
}

export { forEach, map, reduce, upperProps };
78 changes: 78 additions & 0 deletions projects/array-objects/index.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
import { forEach, map, reduce, upperProps } from './index';

describe('ДЗ 3 - объекты и массивы', () => {
describe('forEach', () => {
it('должна вызывать функцию для каждого элемента массива', () => {
const array = [1, 2, 3];
const fn = jest.fn();

forEach(array, fn);

for (let i = 0; i < array.length; i++) {
expect(fn).nthCalledWith(i + 1, array[i], i, array);
}
});
});

describe('map', () => {
it('должна вызывать функцию для каждого элемента массива и не изменять оригинальный массив', () => {
const originalArray = [4, 5, 6];
const array = [...originalArray];
const modified = array.map((el) => el ** 2);
const fn = jest.fn((el) => el ** 2);

expect(map(array, fn)).toEqual(modified);
expect(array).toEqual(originalArray);

for (let i = 0; i < array.length; i++) {
expect(fn).nthCalledWith(i + 1, array[i], i, array);
}
});
});

describe('reduce', () => {
it('должна вызывать функцию для каждого элемента и передавать предыдущий результат первым аргументом', () => {
const originalArray = [7, 8, 9];
const array = [...originalArray];
const modified = array.reduce((all, current) => all + current);
const fn = jest.fn((all, current) => all + current);

expect(reduce(array, fn)).toEqual(modified);
expect(array).toEqual(originalArray);

let sum = array[0];

for (let i = 1; i < array.length; i++) {
expect(fn).nthCalledWith(i, sum, array[i], i, array);
sum += array[i];
}
});

it('должна учитывать initial', () => {
const originalArray = [1, 3, 5];
const array = [...originalArray];
const modified = array.reduce((all, current) => all + current, 10);
const fn = jest.fn((all, current) => all + current);

expect(reduce(array, fn, 10)).toEqual(modified);
expect(array).toEqual(originalArray);

let sum = 10;

for (let i = 0; i < array.length; i++) {
expect(fn).nthCalledWith(i + 1, sum, array[i], i, array);
sum += array[i];
}
});
});

describe('upperProps', () => {
it('должна возвращать массив с именами свойств и преобразовывать эти имена в верхний регистр', () => {
const obj = { a: 1, b: 2 };
const target = ['A', 'B'];
const result = upperProps(obj);

expect(result).toEqual(target);
});
});
});
165 changes: 165 additions & 0 deletions projects/exceptions/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
/* ДЗ 3 - работа с исключениями и отладчиком */

/*
Задание 1:

1.1: Функция isAllTrue принимает массив в параметре array и другую функцию в параметре fn.
Нужно по-очереди запустить функцию fn для всех элементов массива.
isAllTrue должна вернуть true только если fn вернула true для всех элементов массива.
Если хотя бы для одного из элементов массива fn вернула false, то и isAllTrue должна вернуть false.

1.2: Необходимо выбрасывать исключение в случаях:
- array не массив или пустой массив (с текстом "empty array")
для проверки на массив вам может помочь функция Array.isArray()
- fn не является функцией (с текстом "fn is not a function")
для проверки на функцию вам может помочь оператор typeof

Запрещено использовать встроенные методы для работы с массивами

Пример:
isAllTrue([1, 2, 3, 4, 5], n => n < 10) // вернет true (потому что все элементы массива меньше 10)
isAllTrue([100, 2, 3, 4, 5], n => n < 10) // вернет false (потому что как минимум первый элемент больше 10)
*/
function isAllTrue(array, fn) {
if (!Array.isArray(array) || array.length === 0) {
throw new Error ('empty array (пустой массив)');
}

if (typeof fn !== 'function') {
throw new Error('fn is not a function (функции не совпадают)');
}

for (const el of array) {
if (!fn(el)) {
return false;
}
}

return true;
}

/*
Задание 2:

2.1: Функция isSomeTrue принимает массив в параметре array и функцию в параметре fn.
Нужно по-очереди запустить функцию fn для всех элементов массива.
isSomeTrue должна вернуть true только если fn вернула true хотя бы для одного из элементов массива.
Если fn не вернула true ни для одного элементов массива, то и isSomeTrue должна вернуть false.

2.2: Необходимо выбрасывать исключение в случаях:
- array не массив или пустой массив (с текстом "empty array")
для проверки на массив вам может помочь функция Array.isArray()
- fn не является функцией (с текстом "fn is not a function")
для проверки на функцию вам может помочь оператор typeof

Запрещено использовать встроенные методы для работы с массивами

Пример:
isSomeTrue([1, 2, 30, 4, 5], n => n > 20) // вернет true (потому что в массиве есть хотя бы один элемент больше 20)
isSomeTrue([1, 2, 3, 4, 5], n => n > 20) // вернет false (потому что в массиве нет ни одного элемента больше 20)
*/
function isSomeTrue(array, fn) {
if (!Array.isArray(array) || array.length === 0) {
throw new Error ('empty array (пустой массив)');
}

if (typeof fn !== 'function') {
throw new Error('fn is not a function (не является функцией)');
}

for (const el of array) {
if (fn(el)) {
return true;
}
}

return false;
}

/*
Задание 3:

3.1: Функция returnBadArguments принимает заранее неизвестное количество аргументов, первым из которых является функция fn
returnBadArguments должна поочередно запустить fn для каждого переданного аргумента (кроме самой fn)

3.2: returnBadArguments должна вернуть массив аргументов, для которых fn выбросила исключение

3.3: Необходимо выбрасывать исключение в случаях:
- fn не является функцией (с текстом "fn is not a function")
для проверки на функцию вам может помочь оператор typeof
*/
function returnBadArguments(fn, ...args) {
if (typeof fn !== 'function') {
throw new Error('fn is not a function (не является функцией)');
}

const badArgs = [];

for (const arg of args) {
try {
fn(arg);
} catch {
badArgs.push(arg);
}
}

return badArgs;
}

/*
Задание 4:

4.1: Функция calculator имеет параметр number (по умолчанию - 0)

4.2: Функция calculator должна вернуть объект, у которого должно быть несколько методов:
- sum - складывает number с переданными аргументами
- dif - вычитает из number переданные аргументы
- div - делит number на первый аргумент. Результат делится на следующий аргумент (если передан) и так далее
- mul - умножает number на первый аргумент. Результат умножается на следующий аргумент (если передан) и так далее

Количество передаваемых в методы аргументов заранее неизвестно

4.3: Необходимо выбрасывать исключение в случаях:
- number не является числом (с текстом "number is not a number")
- какой-либо из аргументов div является нулем (с текстом "division by 0")

Пример:
const myCalc = calculator(10);

console.log(calc.sum(1, 2, 3)); // выведет 16 (10 + 1 + 2 + 3)
console.log(calc.dif(1, 2, 3)); // выведет 5 (10 - 1 - 2 - 3)
console.log(calc.mul(1, 2, 3)); // выведет 60 (10 * 1 * 2 * 3)
console.log(calc.div(2, 2)); // выведет 2.5 (10 / 2 / 2)
console.log(calc.div(2, 0)); // выбросит исключение, потому что один из аргументов равен 0
*/
function calculator(number = 0) {
if (typeof number !== 'number') {
throw new Error('number is not a number (не является числом)');
}

return {
sum(...args) {
return args.reduce((all, current) => all + current, number);
},

dif(...args) {
return args.reduce((all, current) => all - current, number);
},

div(...args) {
if (args.some(a => a === 0)) {
throw new Error ('division by 0 (деление на 0)')
}

return args.reduce((all, current) => all / current, number)
},

mul(...args) {
return args.reduce((all, current) => all * current, number);
}
}
}

/* При решении задач, постарайтесь использовать отладчик */

export { isAllTrue, isSomeTrue, returnBadArguments, calculator };
Loading