From d71159d390b87ccf39bcd0cc82354a580036f419 Mon Sep 17 00:00:00 2001 From: Robert Date: Mon, 6 Oct 2025 17:18:47 +0200 Subject: [PATCH 1/4] array_method_reduce --- src/reduce.js | 4 +++ src/reduce.test.js | 68 ++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 70 insertions(+), 2 deletions(-) diff --git a/src/reduce.js b/src/reduce.js index 38be21c..796dee2 100644 --- a/src/reduce.js +++ b/src/reduce.js @@ -15,6 +15,10 @@ function reduce(callback, startValue) { prev = this[0]; } + if (arguments.length < 2 && this.length === 0) { + throw new Error('Array can not be empty.'); + } + for (let i = startIndex; i < this.length; i++) { prev = callback(prev, this[i], i, this); } diff --git a/src/reduce.test.js b/src/reduce.test.js index 47a892f..dd85e16 100644 --- a/src/reduce.test.js +++ b/src/reduce.test.js @@ -11,9 +11,73 @@ describe('reduce', () => { delete Array.prototype.reduce2; }); - it('should ', () => { + it('should sum numbers with initial value', () => { + const array = [10, 15, 20]; + const result = array.reduce2((acc, cur) => acc + cur, 10); + + expect(result).toBe(55); + }); + + it('should sum numbers without initial value', () => { + const array = [10, 15, 20]; + + const result = array.reduce2((acc, cur) => acc + cur); + + expect(result).toBe(45); + }); + + it('should add values different from integer', () => { + const array = ['Hello', ' ', 'world!!!']; + + const result = array.reduce2((arr, cur) => arr + cur, ''); + + expect(result).toBe('Hello world!!!'); }); - // Add tests here + it('should pass index or array to callback as arguements', () => { + const array = [3, 5, 7]; + + const mockFn = jest.fn((acc, curr) => acc + curr); + + array.reduce2(mockFn); + + expect(mockFn.mock.calls.length).toBe(2); + + expect(mockFn).toHaveBeenCalledWith(3, 5, 1, array); + expect(mockFn).toHaveBeenCalledWith(8, 7, 2, array); + }); + + it(`should return error, + if array is empty and is lack of initial value`, () => { + expect(() => [].reduce2((a, c) => + a + c)).toThrow('Array can not be empty.'); + }); + + it(`should handle array with element without initial value`, () => { + const array = [10]; + + const result = array.reduce2((arr, curr) => arr + curr); + + expect(result).toBe(10); + }); + + it(`should throw error, if callback is not a function`, () => { + const array = [11, 22, 33]; + + expect(() => array.reduce2(null)).toThrow(TypeError); + expect(() => array.reduce2('function')).toThrow(TypeError); + expect(() => array.reduce2({})).toThrow(TypeError); + expect(() => array.reduce2(100)).toThrow(TypeError); + }); + + it(`should sum array with empty slots`, () => { + // eslint-disable-next-line no-sparse-arrays + const array = [1, , 5]; + + const result = array.reduce2((arr, curr) => + arr + (curr !== undefined && curr !== null ? curr : 0), 0); + + expect(result).toBe(6); + }); }); From 7e99aa4c831aaa38339222feaefb185208dc94bd Mon Sep 17 00:00:00 2001 From: Robert Date: Mon, 6 Oct 2025 17:37:47 +0200 Subject: [PATCH 2/4] problem with loop --- src/reduce.js | 4 ++++ src/reduce.test.js | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/reduce.js b/src/reduce.js index 796dee2..c041759 100644 --- a/src/reduce.js +++ b/src/reduce.js @@ -10,6 +10,10 @@ function reduce(callback, startValue) { let prev = startValue; let startIndex = 0; + if (typeof callback !== 'function') { + throw new Error('Callback has to be function.'); + } + if (arguments.length < 2) { startIndex = 1; prev = this[0]; diff --git a/src/reduce.test.js b/src/reduce.test.js index dd85e16..a4865d2 100644 --- a/src/reduce.test.js +++ b/src/reduce.test.js @@ -51,7 +51,7 @@ describe('reduce', () => { it(`should return error, if array is empty and is lack of initial value`, () => { expect(() => [].reduce2((a, c) => - a + c)).toThrow('Array can not be empty.'); + a + c)).toThrow(TypeError); }); it(`should handle array with element without initial value`, () => { From f93fdcfd9456f05d669c540640df9f2fe6fdc6c1 Mon Sep 17 00:00:00 2001 From: Robert Date: Mon, 6 Oct 2025 17:43:40 +0200 Subject: [PATCH 3/4] problem with loop --- src/reduce.js | 4 ---- src/reduce.test.js | 2 +- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/src/reduce.js b/src/reduce.js index c041759..796dee2 100644 --- a/src/reduce.js +++ b/src/reduce.js @@ -10,10 +10,6 @@ function reduce(callback, startValue) { let prev = startValue; let startIndex = 0; - if (typeof callback !== 'function') { - throw new Error('Callback has to be function.'); - } - if (arguments.length < 2) { startIndex = 1; prev = this[0]; diff --git a/src/reduce.test.js b/src/reduce.test.js index a4865d2..dd85e16 100644 --- a/src/reduce.test.js +++ b/src/reduce.test.js @@ -51,7 +51,7 @@ describe('reduce', () => { it(`should return error, if array is empty and is lack of initial value`, () => { expect(() => [].reduce2((a, c) => - a + c)).toThrow(TypeError); + a + c)).toThrow('Array can not be empty.'); }); it(`should handle array with element without initial value`, () => { From 607785737b7134eaccb2f10f1f27cccac6eea841 Mon Sep 17 00:00:00 2001 From: Robert Date: Mon, 6 Oct 2025 20:24:11 +0200 Subject: [PATCH 4/4] new_solution --- src/reduce.js | 8 ++--- src/reduce.test.js | 85 +++++++++++++++++++++------------------------- 2 files changed, 42 insertions(+), 51 deletions(-) diff --git a/src/reduce.js b/src/reduce.js index 796dee2..d07f59c 100644 --- a/src/reduce.js +++ b/src/reduce.js @@ -15,12 +15,10 @@ function reduce(callback, startValue) { prev = this[0]; } - if (arguments.length < 2 && this.length === 0) { - throw new Error('Array can not be empty.'); - } - for (let i = startIndex; i < this.length; i++) { - prev = callback(prev, this[i], i, this); + if (i in this) { + prev = callback(prev, this[i], i, this); + } } return prev; diff --git a/src/reduce.test.js b/src/reduce.test.js index dd85e16..7d07230 100644 --- a/src/reduce.test.js +++ b/src/reduce.test.js @@ -2,6 +2,10 @@ const { reduce } = require('./reduce'); +const nums = [1, 2, 3, 4]; +const strings = ['1', '2', '3']; +let callback; + describe('reduce', () => { beforeAll(() => { Array.prototype.reduce2 = reduce; // eslint-disable-line @@ -11,73 +15,62 @@ describe('reduce', () => { delete Array.prototype.reduce2; }); - it('should sum numbers with initial value', () => { - const array = [10, 15, 20]; - - const result = array.reduce2((acc, cur) => acc + cur, 10); - - expect(result).toBe(55); + beforeEach(() => { + callback = jest.fn((acc, curr) => acc + curr); }); - it('should sum numbers without initial value', () => { - const array = [10, 15, 20]; - - const result = array.reduce2((acc, cur) => acc + cur); - - expect(result).toBe(45); + it('should have instance of function', () => { + expect(reduce).toBeInstanceOf(Function); }); - it('should add values different from integer', () => { - const array = ['Hello', ' ', 'world!!!']; + it('should use callback for all items in array', () => { + const init = 10; - const result = array.reduce2((arr, cur) => arr + cur, ''); + nums.reduce2(callback, init); - expect(result).toBe('Hello world!!!'); + expect(callback).toHaveBeenCalledTimes(nums.length); }); - it('should pass index or array to callback as arguements', () => { - const array = [3, 5, 7]; - - const mockFn = jest.fn((acc, curr) => acc + curr); + it('should work without initial value', () => { + const result = nums.reduce2(callback); - array.reduce2(mockFn); + expect(callback).toHaveBeenCalled(); + expect(callback).toHaveBeenCalledTimes(3); + expect(result).toBe(10); + }); - expect(mockFn.mock.calls.length).toBe(2); + it('should work without initial array', () => { + const init = 10; + const result = [].reduce2(callback, init); - expect(mockFn).toHaveBeenCalledWith(3, 5, 1, array); - expect(mockFn).toHaveBeenCalledWith(8, 7, 2, array); + expect(callback).not.toHaveBeenCalled(); + expect(callback).toHaveBeenCalledTimes(0); + expect(result).toBe(10); }); - it(`should return error, - if array is empty and is lack of initial value`, () => { - expect(() => [].reduce2((a, c) => - a + c)).toThrow('Array can not be empty.'); - }); + it('should return undefined without array and initial value', () => { + const result = [].reduce2(callback); - it(`should handle array with element without initial value`, () => { - const array = [10]; + expect(result).toBe(undefined); + expect(callback).not.toHaveBeenCalled(); + }); - const result = array.reduce2((arr, curr) => arr + curr); + it('should work with strings', () => { + const check = '123'; + const result = strings.reduce2(callback); - expect(result).toBe(10); + expect(result).toBe(check); }); - it(`should throw error, if callback is not a function`, () => { - const array = [11, 22, 33]; + it('should skip initial value if it is specified', () => { + const result = [1, 1, 2].reduce2(callback, null); - expect(() => array.reduce2(null)).toThrow(TypeError); - expect(() => array.reduce2('function')).toThrow(TypeError); - expect(() => array.reduce2({})).toThrow(TypeError); - expect(() => array.reduce2(100)).toThrow(TypeError); + expect(result).toBe(4); }); - it(`should sum array with empty slots`, () => { - // eslint-disable-next-line no-sparse-arrays - const array = [1, , 5]; - - const result = array.reduce2((arr, curr) => - arr + (curr !== undefined && curr !== null ? curr : 0), 0); + it('should invoke callback for indexes without value', () => { + [1, '', '', 1, 2].reduce2(callback); - expect(result).toBe(6); + expect(callback).toHaveBeenCalledTimes(4); }); });