Skip to content
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
132 changes: 132 additions & 0 deletions src/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
/* ДЗ 2 - работа с массивами и объеектами */

/*
Задание 1:

Напишите аналог встроенного метода forEach для работы с массивами
Посмотрите как работает forEach и повторите это поведение для массива, который будет передан в параметре array
*/
function forEach(array, fn) {
for (let i = 0; i < array.length; i++) {
fn(array[i], i, array)
}
}

/*
Задание 2:

Напишите аналог встроенного метода map для работы с массивами
Посмотрите как работает map и повторите это поведение для массива, который будет передан в параметре array
*/
function map(array, fn) {
let newArr = [];

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

return newArr;
}

/*
Задание 3:

Напишите аналог встроенного метода reduce для работы с массивами
Посмотрите как работает reduce и повторите это поведение для массива, который будет передан в параметре array
*/
function reduce(array, fn, initial) {
let i;

if (initial == undefined) {
initial = array[0];
i=1;
} else {
i=0;
}
for (; i<array.length; i++) {
initial = fn(initial, array[i], i, array);
}

return initial;
}

/*
Задание 4:

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

Пример:
upperProps({ name: 'Сергей', lastName: 'Петров' }) вернет ['NAME', 'LASTNAME']
*/
function upperProps(obj) {
let arr = [];
let key = Object.keys(obj).length;

for (let i = 0; i < key; i++) {
arr.push(Object.keys(obj)[i].toUpperCase());
}

return arr
}

/*
Задание 5 *:

Напишите аналог встроенного метода slice для работы с массивами
Посмотрите как работает slice и повторите это поведение для массива, который будет передан в параметре array
*/
function slice(array, from = 0, to = array.length) {
let newArr =[];

if (from > array.length) {
from = array.length;
}
if (to > array.length) {
to = array.length;
}
if (from < 0 && from + array.length < 0) {
from =0;
}
if (from < 0 && from + array.length > 0) {
from = from + array.length;
}
if (to < 0 && to + array.length < 0) {
to = 0;
}
if (to < 0 && to + array.length > 0) {
to = to + array.length;
}
for (let i = from; i<to; i++) {
newArr.push(array[i]);
}

return newArr;
}

/*
Задание 6 *:

Функция принимает объект и должна вернуть Proxy для этого объекта
Proxy должен перехватывать все попытки записи значений свойств и возводить это значение в квадрат
*/
function createProxy(obj) {

let proxy = new Proxy(obj, {
set(target, prop, value) {
target[prop] = value * value;

return target[prop];
}
});

return proxy;
}

export {
forEach,
map,
reduce,
upperProps,
slice,
createProxy
};
260 changes: 256 additions & 4 deletions test/index.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,259 @@
import assert from 'assert';
const nativeSlice = Array.prototype.slice;
const nativeMap = Array.prototype.map;
const nativeReduce = Array.prototype.reduce;

describe('Test', () => {
it('should work', () => {
assert(true == true);
import { assert } from 'chai';
import { randomValue as random, randomNumberArray } from '../helper';
import {
forEach,
map,
reduce,
upperProps,
slice,
createProxy
} from '../src/index';

describe('ДЗ 3 - объекты и массивы', () => {
describe('forEach', () => {
it('должна вызывать функцию для каждого элемента массива и передавать элемент первым аргументом', () => {
let array = randomNumberArray();
let passed = [];

forEach(array, el => passed.push(el));

assert.deepEqual(array, passed);
});

it('должна передавать индекс элемента вторым аргументом', () => {
let array = randomNumberArray();
let index = 0;

forEach(array, (el, i) => assert.equal(i, index++));
});

it('должна передавать сам массив третьим аргументом', () => {
let array = randomNumberArray();

forEach(array, (el, i, a) => assert.strictEqual(a, array));
});
});

describe('map', () => {
it('должна вызывать функцию для каждого элемента массива и передавать элемент первым аргументом', () => {
let array = randomNumberArray();
let passed = [];

map(array, el => passed.push(el));

assert.deepEqual(array, passed);
});

it('должна передавать индекс элемента вторым аргументом', () => {
let array = randomNumberArray();
let index = 0;

map(array, (el, i) => assert.equal(i, index++));
});

it('должна передавать сам массив третьим аргументом', () => {
let array = randomNumberArray();

map(array, (el, i, a) => assert.strictEqual(a, array));
});

it('должна возвращать измененную копию массива', () => {
let array = randomNumberArray();
let target = nativeMap.call(array, el => el ** 2);
let result = map(array, el => el ** 2);

assert.deepEqual(result, target);
});

it('не должна изменять оригинальный массив', () => {
let array = randomNumberArray();
let arrayCopy = nativeSlice.call(array);

map(array, el => el ** 2);
assert.deepEqual(array, arrayCopy);
});
});

describe('reduce', () => {
it('должна вызывать функцию для каждого элемента и передавать предыдущий результат первым аргументом', () => {
let array = randomNumberArray();
let i = 0;
let prevResult = array[0];

reduce(array, prev => {
assert.equal(prev, prevResult);

return prevResult = i++;
});
});

it('должна учитывать initial', () => {
let array = randomNumberArray();
let passed = [];
let initial = random('number');

reduce(array, prev => passed.push(prev), initial);
assert.deepEqual(passed[0], initial);
});

it('если initial не указан, то при первой итерации в prev передается первый элемент массива', () => {
let array = randomNumberArray();
let passed = [];

reduce(array, prev => passed.push(prev));
assert.strictEqual(passed[0], array[0]);
});

it('должна передавать элемент вторым аргументом', () => {
let array = randomNumberArray();
let passed = [];
let initial = random('number');

reduce(array, (prev, el) => passed.push(el));
assert.deepEqual(array.slice(1), passed);

passed = [];
reduce(array, (prev, el) => passed.push(el), initial); // с учетом initial
assert.deepEqual(array, passed);
});

it('должна передавать индекс элемента третьим аргументом', () => {
let array = randomNumberArray();
let index = 1;
let initial = random('number');

reduce(array, (prev, el, i) => assert.equal(i, index++));

index = 0;
reduce(array, (prev, el, i) => assert.equal(i, index++), initial); // с учетом initial
});

it('должна передавать сам массив четвертым аргументом', () => {
let array = randomNumberArray();

reduce(array, (prev, el, i, a) => assert.strictEqual(a, array));
});

it('не должна изменять оригинальный массив', () => {
let array = randomNumberArray();
let arrayCopy = nativeSlice.call(array);

reduce(array, el => el ** 2);
assert.deepEqual(array, arrayCopy);
});

it('общая проверка работоспособности', () => {
let array = randomNumberArray();
let target = nativeReduce.call(array, (prev, el) => prev + el);
let result = reduce(array, (prev, el) => prev + el);
let initial = random('number');

assert.deepEqual(result, target);

target = nativeReduce.call(array, (prev, el) => prev + el, initial);
result = reduce(array, (prev, el) => prev + el, initial);
assert.deepEqual(result, target);
});
});

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

assert.deepEqual(result, target);
});
});

describe('slice', () => {
it('общая проверка работоспособности', () => {
let array = [1, 2, 3, 4, 5, 6, 7];
let target = nativeSlice.call(array);
let result = slice(array);

assert.deepEqual(result, target);

target = nativeSlice.call(array, 0);
result = slice(array, 0);
assert.deepEqual(result, target);

target = nativeSlice.call(array, 0, 0);
result = slice(array, 0, 0);
assert.deepEqual(result, target);

target = nativeSlice.call(array, 0, 1);
result = slice(array, 0, 1);
assert.deepEqual(result, target);

target = nativeSlice.call(array, 0, 2);
result = slice(array, 0, 2);
assert.deepEqual(result, target);

target = nativeSlice.call(array, 0, 5);
result = slice(array, 0, 5);
assert.deepEqual(result, target);

target = nativeSlice.call(array, 0, -1);
result = slice(array, 0, -1);
assert.deepEqual(result, target);

target = nativeSlice.call(array, 0, -3);
result = slice(array, 0, -3);
assert.deepEqual(result, target);

target = nativeSlice.call(array, 0, -10000);
result = slice(array, 0, -10000);
assert.deepEqual(result, target);

target = nativeSlice.call(array, 3);
result = slice(array, 3);
assert.deepEqual(result, target);

target = nativeSlice.call(array, 3, -100);
result = slice(array, 3, -100);
assert.deepEqual(result, target);

target = nativeSlice.call(array, 3, 100);
result = slice(array, 3, 100);
assert.deepEqual(result, target);

target = nativeSlice.call(array, 3, 5);
result = slice(array, 3, 5);
assert.deepEqual(result, target);

target = nativeSlice.call(array, 9999);
result = slice(array, 9999);
assert.deepEqual(result, target);

target = nativeSlice.call(array, -9999);
result = slice(array, -9999);
assert.deepEqual(result, target);

target = nativeSlice.call(array, -9999, 4);
result = slice(array, -9999, 4);
assert.deepEqual(result, target);

target = nativeSlice.call(array, -9999, -4);
result = slice(array, -9999, -4);
assert.deepEqual(result, target);
});
});

describe('createProxy', () => {
it('должна вернуть Proxy, который возводит в квадрат любое записываемое значение', () => {
let obj = {};

obj = createProxy(obj);

obj.a = 2;
obj.b = 5;

assert.deepEqual(obj, { a: 4, b: 25 });
});
});
});