From abdebe24d3c81ed665c9843f6f87bd3978be2217 Mon Sep 17 00:00:00 2001 From: Vlad Possin Date: Tue, 24 Nov 2020 16:19:52 +0600 Subject: [PATCH] homework_2 created --- projects/homework_2/index.js | 88 +++++++++++++++++++++++++++++ projects/homework_2/index.spec.js | 92 +++++++++++++++++++++++++++++++ 2 files changed, 180 insertions(+) create mode 100644 projects/homework_2/index.js create mode 100644 projects/homework_2/index.spec.js diff --git a/projects/homework_2/index.js b/projects/homework_2/index.js new file mode 100644 index 0000000..1cc252f --- /dev/null +++ b/projects/homework_2/index.js @@ -0,0 +1,88 @@ +/* ДЗ 2 - работа с массивами и объектами */ + +/* + Задание 1: + + Напишите аналог встроенного метода forEach для работы с массивами + Посмотрите как работает forEach и повторите это поведение для массива, который будет передан в параметре array + + Пример: + forEach([1, 2, 3], (el) => console.log(el)) + */ +function forEach(array, fn) { + for (let i = 0; i < array.length; i++) { + fn(array[i], i, array); + } +} + +/* + Задание 2: + + Напишите аналог встроенного метода map для работы с массивами + Посмотрите как работает map и повторите это поведение для массива, который будет передан в параметре array + + Пример: + map([1, 2, 3], (el) => el ** 2) // [1, 4, 9] + */ +function map(array, fn) { + const modified = []; + for (let i = 0; i < array.length; i++) { + modified[i] = fn(array[i], i, array); + } + + return modified; +} + +/* + Задание 3: + + Напишите аналог встроенного метода reduce для работы с массивами + Посмотрите как работает reduce и повторите это поведение для массива, который будет передан в параметре array + + Пример: + reduce([1, 2, 3], (all, current) => all + current) // 6 + */ +function reduce(array, fn, initial) { + const hasInitial = typeof initial !== 'undefined'; + let prev = hasInitial ? initial : array[0]; + + for (let i = hasInitial ? 0 : 1; i < array.length; i++) { + prev = fn(prev, array[i], i, array); + } + + return prev; +} + +/* +Задание 4: + +Функция должна перебрать все свойства объекта, преобразовать их имена в верхний регистр и вернуть в виде массива + +Пример: +upperProps({ name: 'Сергей', lastName: 'Петров' }) вернет ['NAME', 'LASTNAME'] +*/ +function upperProps(obj) { + return Object.keys(obj).map((name) => name.toUpperCase()); +} + +/* + Задание 5 *: + + Функция принимает объект и должна вернуть Proxy для этого объекта + Proxy должен перехватывать все попытки записи значений свойств и возводить это значение в квадрат + + Пример: + const obj = createProxy({}); + obj.foo = 2; + console.log(obj.foo); // 4 + */ +function createProxy(obj) { + return new Proxy(obj, { + set(obj, key, value) { + obj[key] = value ** 2; + return true; + }, + }); +} + +export { forEach, map, reduce, upperProps, createProxy }; diff --git a/projects/homework_2/index.spec.js b/projects/homework_2/index.spec.js new file mode 100644 index 0000000..5038e2a --- /dev/null +++ b/projects/homework_2/index.spec.js @@ -0,0 +1,92 @@ +import { randomNumberArray } from '../../scripts/helper'; +import { createProxy, forEach, map, reduce, upperProps } from './index'; + +describe('ДЗ 3 - объекты и массивы', () => { + describe('forEach', () => { + it('должна вызывать функцию для каждого элемента массива', () => { + const array = randomNumberArray(); + 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 = randomNumberArray(); + 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 = randomNumberArray(); + 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 = randomNumberArray(); + 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); + }); + }); + + describe('createProxy', () => { + it('должна вернуть Proxy, который возводит в квадрат любое записываемое значение', () => { + let obj = {}; + + obj = createProxy(obj); + + obj.a = 2; + obj.b = 5; + + expect(obj).toEqual({ a: 4, b: 25 }); + }); + }); +});