├── babel.config.js ├── arrays ├── exercises │ ├── __tests__ │ │ ├── 01-fill.test.js │ │ ├── 04-from-pairs.test.js │ │ ├── 08-flatten.test.js │ │ ├── 03-compact.test.js │ │ ├── 05-without.test.js │ │ ├── 09-chunk.test.js │ │ ├── 02-reverse.test.js │ │ ├── 06-unique.test.js │ │ ├── 07-is-equal.test.js │ │ └── 10-intersection.test.js │ ├── 02-reverse.js │ ├── 08-flatten.js │ ├── 04-from-pairs.js │ ├── 06-unique.js │ ├── 10-intersection.js │ ├── 01-fill.js │ ├── 03-compact.js │ ├── 05-without.js │ ├── 09-chunk.js │ └── 07-is-equal.js └── solutions │ ├── __tests__ │ ├── 01-fill.test.js │ ├── 04-from-pairs.test.js │ ├── 08-flatten.test.js │ ├── 03-compact.test.js │ ├── 09-chunk.test.js │ ├── 05-without.test.js │ ├── 07-is-equal.test.js │ ├── 02-reverse.test.js │ ├── 06-unique.test.js │ └── 10-intersection.test.js │ ├── 01-fill.js │ ├── 08-flatten.js │ ├── 03-compact.js │ ├── 04-from-pairs.js │ ├── 09-chunk.js │ ├── 07-is-equal.js │ ├── 10-intersection.js │ ├── 06-unique.js │ ├── 02-reverse.js │ └── 05-without.js ├── .editorconfig ├── objects ├── exercises │ ├── 02-make-pairs.js │ ├── 01-is-plain-object.js │ ├── 04-is-empty.js │ ├── 03-without.js │ ├── 07-is-empty-deep.js │ ├── 09-intersection.js │ ├── 10-intersection-deep.js │ ├── 06-invoke.js │ ├── 08-is-equal-deep.js │ ├── 05-is-equal.js │ └── __tests__ │ │ ├── 02. make-pairs.test.js │ │ ├── 06-invoke.test.js │ │ ├── 09-intersection.test.js │ │ ├── 05-is-equal.test.js │ │ ├── 01-is-plain-object.test.js │ │ ├── 03-without.test.js │ │ ├── 04-is-empty.test.js │ │ ├── 10-intersection-deep.test.js │ │ ├── 08-is-equal-deep.test.js │ │ └── 07-is-empty-deep.test.js └── solutions │ ├── 01-is-plain-object.js │ ├── 03-without.js │ ├── 04-is-empty.js │ ├── 06-invoke.js │ ├── 09-intersection.js │ ├── __tests__ │ ├── 06-invoke.test.js │ ├── 09-intersection.test.js │ ├── 01-is-plain-object.test.js │ ├── 03-without.test.js │ ├── 02. make-pairs.test.js │ ├── 05-is-equal.test.js │ ├── 04-is-empty.test.js │ ├── 10-intersection-deep.test.js │ ├── 08-is-equal-deep.test.js │ └── 07-is-empty-deep.test.js │ ├── 02-make-pairs.js │ ├── 10-intersection-deep.js │ ├── 05-is-equal.js │ ├── 07-is-empty-deep.js │ └── 08-is-equal-deep.js ├── .gitignore ├── .eslintrc.json ├── package.json └── readme.md /babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: [ 3 | [ 4 | '@babel/preset-env', 5 | { 6 | targets: { 7 | node: 'current', 8 | }, 9 | }, 10 | ], 11 | ], 12 | }; 13 | -------------------------------------------------------------------------------- /arrays/exercises/__tests__/01-fill.test.js: -------------------------------------------------------------------------------- 1 | import { fill } from '../01-fill'; 2 | 3 | describe('fill function tests', () => { 4 | it('should return ["a", "a", "a"]', () => { 5 | expect(fill(3, 'a')).toEqual(['a', 'a', 'a']); 6 | }); 7 | }); 8 | -------------------------------------------------------------------------------- /arrays/solutions/__tests__/01-fill.test.js: -------------------------------------------------------------------------------- 1 | import { fill } from '../01-fill'; 2 | 3 | describe('solution of fill function tests', () => { 4 | it('should return ["a", "a", "a"]', () => { 5 | expect(fill(3, 'a')).toEqual(['a', 'a', 'a']); 6 | }); 7 | }); 8 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # Editor configuration, see http://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | charset = utf-8 6 | indent_style = space 7 | indent_size = 2 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true 10 | end_of_line = lf 11 | 12 | [*.md] 13 | max_line_length = off 14 | trim_trailing_whitespace = false 15 | -------------------------------------------------------------------------------- /arrays/exercises/__tests__/04-from-pairs.test.js: -------------------------------------------------------------------------------- 1 | import { fromPairs } from '../04-from-pairs'; 2 | 3 | describe('fromPairs function tests', () => { 4 | it('should return an object with pairs', () => { 5 | const data = [['a', 1], ['b', '2'], ['c', undefined]]; 6 | expect(fromPairs(data)).toEqual({ a: 1, b: '2', c: undefined }); 7 | }); 8 | }); 9 | -------------------------------------------------------------------------------- /arrays/solutions/__tests__/04-from-pairs.test.js: -------------------------------------------------------------------------------- 1 | import { fromPairs } from '../04-from-pairs'; 2 | 3 | describe('solution of fromPairs function tests', () => { 4 | it('should return an object with pairs', () => { 5 | const data = [['a', 1], ['b', '2'], ['c', undefined]]; 6 | expect(fromPairs(data)).toEqual({ a: 1, b: '2', c: undefined }); 7 | }); 8 | }); 9 | -------------------------------------------------------------------------------- /arrays/exercises/02-reverse.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Task description: Write a method that reverts input array 3 | * Expected Result: [1, 2, 3] => [3, 2, 1] 4 | * Task Complexity: 1 of 5 5 | * @param {Array} array - Array of any elements 6 | * @returns {Array} 7 | */ 8 | export const reverse = (array) => { 9 | throw new Error(`put your solution here ${array}`); 10 | }; 11 | -------------------------------------------------------------------------------- /arrays/exercises/08-flatten.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Task description: Write a method that turns a deep array into a plain array 3 | * Expected Result: [1, 2, [3, 4, [5]]] => [1, 2, 3, 4, 5] 4 | * Task complexity: 3 of 5 5 | * @param {Array} array - A deep array 6 | * @returns {Array} 7 | */ 8 | export const flatten = (array) => { 9 | throw new Error(`put your solution here ${array}`); 10 | }; 11 | -------------------------------------------------------------------------------- /arrays/solutions/01-fill.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Task description: Write a method that creates a new array with given values 3 | * Expected Result: (3, 'a') => ['a', 'a', 'a'] 4 | * Task Complexity: 1 of 5 5 | * @param {number} arraySize - size of array 6 | * @param {?} value - value to fill 7 | * @returns {Array} 8 | */ 9 | export const fill = (arraySize, value) => new Array(arraySize).fill(value); 10 | -------------------------------------------------------------------------------- /arrays/solutions/08-flatten.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Task description: Write a method that turns a deep array into a plain array 3 | * Expected Result: [1, 2, [3, 4, [5]]] => [1, 2, 3, 4, 5] 4 | * Task complexity: 3 of 5 5 | * @param {Array} array - A deep array 6 | * @returns {Array} 7 | */ 8 | export const flatten = (array) => array.reduce((acc, val) => acc.concat(Array.isArray(val) ? flatten(val) : val), []); 9 | -------------------------------------------------------------------------------- /arrays/exercises/04-from-pairs.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Task description: Write a method that returns an object composed of key-value pairs. 3 | * Expected Result: [['a', 1], ['b', 2]] => { a: 1, b: 2 } 4 | * Task Complexity: 2 of 5 5 | * @param {Array} array - a deep array of pairs 6 | * @returns {Array} 7 | */ 8 | export const fromPairs = (array) => { 9 | throw new Error(`put your solution here ${array}`); 10 | }; 11 | -------------------------------------------------------------------------------- /arrays/solutions/03-compact.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Task description: Write a method that clears array from all unnecessary elements, like false, undefined, empty strings, zero, null 3 | * Expected Result: [0, 1, false, 2, undefined, '', 3, null] => [1, 2, 3] 4 | * Task Complexity: 1 of 5 5 | * @param {Array} array - An array of any elements 6 | * @returns {Array} 7 | */ 8 | export const compact = (array) => array.filter((el) => el); 9 | -------------------------------------------------------------------------------- /arrays/exercises/06-unique.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Task description: Write a method that returns a duplicate-free array 3 | * Expected Result: Duplicate-free array [1, 2, 3, 1, 2] => [1, 2, 3] 4 | * Task Complexity: 2 of 5 5 | * @param {Array} array - Array of primitive data types 6 | * @returns {Array} 7 | */ 8 | export const unique = (array) => { 9 | throw new Error(`put your solution here ${array}`); 10 | }; 11 | -------------------------------------------------------------------------------- /arrays/exercises/10-intersection.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Task description: Write a method that creates an array of unique values that are included in all given arrays 3 | * Expected Result: ([1, 2], [2, 3]) => [2] 4 | * Task complexity: 4 of 5 5 | * @param {?} arrays - Arrays of primitive data types 6 | * @returns {Array} 7 | */ 8 | export const intersection = (...arrays) => { 9 | throw new Error(`put your solution here ${arrays}`); 10 | }; 11 | -------------------------------------------------------------------------------- /objects/exercises/02-make-pairs.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Task description: Write a method that returns a deep array like [[key, value]] 3 | * Expected Result: ({ a: 1, b: 2 }) => [['a', 1], ['b', 2]] 4 | * Task complexity: 1 of 5 5 | * @param {Object} object - Any object to transform into array 6 | * @returns {Array} - a deep array 7 | */ 8 | export const makePairs = (object) => { 9 | throw new Error(`put your solution here ${object}`); 10 | }; 11 | -------------------------------------------------------------------------------- /arrays/exercises/01-fill.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Task description: Write a method that creates a new array with given values 3 | * Expected Result: (3, 'a') => ['a', 'a', 'a'] 4 | * Task Complexity: 1 of 5 5 | * @param {number} arraySize - size of array 6 | * @param {?} value - value to fill 7 | * @returns {Array} 8 | */ 9 | export const fill = (arraySize, value) => { 10 | throw new Error(`put your solution here ${arraySize}, ${value}`); 11 | }; 12 | -------------------------------------------------------------------------------- /arrays/exercises/03-compact.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Task description: Write a method that clears array from all unnecessary elements, like false, undefined, empty strings, zero, null 3 | * Expected Result: [0, 1, false, 2, undefined, '', 3, null] => [1, 2, 3] 4 | * Task Complexity: 1 of 5 5 | * @param {Array} array - An array of any elements 6 | * @returns {Array} 7 | */ 8 | export const compact = (array) => { 9 | throw new Error(`put your solution here ${array}`); 10 | }; 11 | -------------------------------------------------------------------------------- /arrays/exercises/05-without.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Task description: Write a method that returns an array without listed values 3 | * Expected Result: [1, 2, 3, 1, 2] without 1, 2 => [3] 4 | * Task Complexity: 2 of 5 5 | * @param {Array} array - Array of primitive data types 6 | * @param {?} args list of values to remove 7 | * @returns {Array} 8 | */ 9 | export const without = (array, ...args) => { 10 | throw new Error(`put your solution here ${array} ${args}`); 11 | }; 12 | -------------------------------------------------------------------------------- /arrays/exercises/09-chunk.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Task description: Write a method that splits an array into parts of determined size 3 | * Expected Result: ([1, 2, 3, 4, 5], 2) => [[1, 2], [3, 4], [5]] 4 | * Task complexity: 3 of 5 5 | * @param {Array} array - An array of any elements 6 | * @param {number} size - size of chunks 7 | * @returns {Array} 8 | */ 9 | export const chunk = (array, size) => { 10 | throw new Error(`put your solution here ${array} ${size}`); 11 | }; 12 | -------------------------------------------------------------------------------- /objects/exercises/01-is-plain-object.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Task description: Write a method that verifies an argument is a plain object, not an array or null 3 | * Expected Result: True if object is plain, false otherwise. ({ a: 1 }) => true, ([1, 2, 3]) => false 4 | * Task complexity: 1 of 5 5 | * @param element - element to verify 6 | * @returns {boolean} 7 | */ 8 | export const isPlainObject = (element) => { 9 | throw new Error(`put your solution here ${element}`); 10 | }; 11 | -------------------------------------------------------------------------------- /objects/solutions/01-is-plain-object.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Task description: Write a method that verifies an argument is a plain object, not an array or null 3 | * Expected Result: True if object is plain, false otherwise. ({ a: 1 }) => true, ([1, 2, 3]) => false 4 | * Task complexity: 1 of 5 5 | * @param element - element to verify 6 | * @returns {boolean} 7 | */ 8 | export const isPlainObject = (element) => typeof element === 'object' && !Array.isArray(element) && element !== null; 9 | -------------------------------------------------------------------------------- /arrays/solutions/04-from-pairs.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Task description: Write a method that returns an object composed of key-value pairs. 3 | * Expected Result: [['a', 1], ['b', 2]] => { a: 1, b: 2 } 4 | * Task Complexity: 2 of 5 5 | * @param {Array} array - a deep array of pairs 6 | * @returns {Array} 7 | */ 8 | export const fromPairs = (array) => array.reduce((acc, value) => { 9 | if (Array.isArray(value)) { 10 | acc[value[0]] = value[1]; 11 | } 12 | return acc; 13 | }, {}); 14 | -------------------------------------------------------------------------------- /objects/exercises/04-is-empty.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Task description: Write a method that makes a shallow check is object empty 3 | * Expected Result: ({}) => true, ({ a: undefined }) => true, ({ a: 1 }) => false 4 | * Empty values: '', null, NaN, undefined 5 | * Task complexity: 2 of 5 6 | * @param {Object} object - Object with values of primitive data types 7 | * @returns {boolean} 8 | */ 9 | export const isEmpty = (object) => { 10 | throw new Error(`put your solution here ${object}`); 11 | }; 12 | -------------------------------------------------------------------------------- /arrays/exercises/__tests__/08-flatten.test.js: -------------------------------------------------------------------------------- 1 | import { flatten } from '../08-flatten'; 2 | 3 | describe('flatten function tests', () => { 4 | it('should make an array flat', () => { 5 | const data = [1, 2, [3, 4, [5]]]; 6 | 7 | expect(flatten(data)).toEqual([1, 2, 3, 4, 5]); 8 | }); 9 | it('should return a new flattened array', () => { 10 | const data = [1, 2, [3, 4, [5]]]; 11 | 12 | const result1 = flatten(data); 13 | expect(result1 === data).toBe(false); 14 | }); 15 | }); 16 | -------------------------------------------------------------------------------- /arrays/solutions/__tests__/08-flatten.test.js: -------------------------------------------------------------------------------- 1 | import { flatten } from '../08-flatten'; 2 | 3 | describe('solution of flatten function tests', () => { 4 | it('should make an array flat', () => { 5 | const data = [1, 2, [3, 4, [5]]]; 6 | 7 | expect(flatten(data)).toEqual([1, 2, 3, 4, 5]); 8 | }); 9 | it('should return a new flattened array', () => { 10 | const data = [1, 2, [3, 4, [5]]]; 11 | 12 | const result1 = flatten(data); 13 | expect(result1 === data).toBe(false); 14 | }); 15 | }); 16 | -------------------------------------------------------------------------------- /objects/exercises/03-without.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Task description: Write a method that returns a new object without provided properties 3 | * Expected Result: ({ a: 1, b: 2 }, 'b') => { a: 1 } 4 | * Task complexity: 2 of 5 5 | * @param {Object} object - Any object 6 | * @param {?} args - list of properties to remove from object 7 | * @returns {Object} - New object without listed values 8 | */ 9 | export const without = (object, ...args) => { 10 | throw new Error(`put your solution here ${object} ${args}`); 11 | }; 12 | -------------------------------------------------------------------------------- /objects/exercises/07-is-empty-deep.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Task description: Write a method that makes a deep check is an object empty 3 | * Empty values: '', null, NaN, undefined, [], {} 4 | * Expected Result: ({}) => true, ({ a: { b: undefined } }) => true, ({ a: { b: [] } }) => true 5 | * Task complexity: 3 of 5 6 | * @param {?} element - Object with values of any data types 7 | * @returns {boolean} 8 | */ 9 | export const isEmptyDeep = (element) => { 10 | throw new Error(`put your solution here ${element}`); 11 | }; 12 | -------------------------------------------------------------------------------- /arrays/exercises/__tests__/03-compact.test.js: -------------------------------------------------------------------------------- 1 | import { compact } from '../03-compact'; 2 | 3 | describe('compact function tests', () => { 4 | it('should return [1, 2, 3]', () => { 5 | const data = [0, 1, false, 2, undefined, '', 3, null]; 6 | 7 | expect(compact(data)).toEqual([1, 2, 3]); 8 | }); 9 | it('should return a new compacted array', () => { 10 | const data = [0, 1, false, 2, undefined, '', 3, null]; 11 | 12 | const result1 = compact(data); 13 | expect(result1 === data).toBe(false); 14 | }); 15 | }); 16 | -------------------------------------------------------------------------------- /arrays/exercises/07-is-equal.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Task description: Write a method that makes a shallow compare of two arrays and returns true if they are identical. 3 | * Expected Result: ([1, 2, 3], [1, 2, 3]) => true 4 | * Task Complexity: 2 of 5 5 | * @param {Array} firstArray - Array of primitive data types 6 | * @param {Array} secondArray - Array of primitive data types 7 | * @returns {boolean} 8 | */ 9 | export const isEqual = (firstArray, secondArray) => { 10 | throw new Error(`put your solution here ${firstArray} ${secondArray}`); 11 | }; 12 | -------------------------------------------------------------------------------- /arrays/solutions/__tests__/03-compact.test.js: -------------------------------------------------------------------------------- 1 | import { compact } from '../03-compact'; 2 | 3 | describe('solution of compact function tests', () => { 4 | it('should return [1, 2, 3]', () => { 5 | const data = [0, 1, false, 2, undefined, '', 3, null]; 6 | 7 | expect(compact(data)).toEqual([1, 2, 3]); 8 | }); 9 | it('should return a new compacted array', () => { 10 | const data = [0, 1, false, 2, undefined, '', 3, null]; 11 | 12 | const result1 = compact(data); 13 | expect(result1 === data).toBe(false); 14 | }); 15 | }); 16 | -------------------------------------------------------------------------------- /objects/exercises/09-intersection.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Task description: Write a method that finds shallow intersections of objects 3 | * Expected Result: ({ a: 1, b: 2 }, { c: 1, b: 2 }) => { b: 2 } 4 | * @param {Object} firstObj - Object with values of primitive data types 5 | * @param {Object} secondObj - Object with values of primitive data types 6 | * @returns {Object} 7 | */ 8 | export const intersection = (firstObj, secondObj) => { 9 | throw new Error(`put your solution here ${firstObj} ${secondObj}`); 10 | }; 11 | -------------------------------------------------------------------------------- /objects/exercises/10-intersection-deep.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Task description: Write a method that finds all intersections of objects 3 | * Expected Result: ({ a: 1, b: { c: 3 } }, { c: 1, b: { c: 3 } }) => { b: { c: 3 } } 4 | * @param {Object} firstObj - Object with values of any data types 5 | * @param {Object} secondObj - Object with values of any data types 6 | * @returns {Object} 7 | */ 8 | export const intersectionDeep = (firstObj, secondObj) => { 9 | throw new Error(`put your solution here ${firstObj} ${secondObj}`); 10 | }; 11 | -------------------------------------------------------------------------------- /objects/solutions/03-without.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Task description: Write a method that returns a new object without provided properties 3 | * Expected Result: ({ a: 1, b: 2 }, 'b') => { a: 1 } 4 | * Task complexity: 2 of 5 5 | * @param {Object} object - Any object 6 | * @param {?} args - list of properties to remove from object 7 | * @returns {Object} - New object without listed values 8 | */ 9 | export const without = (object, ...args) => { 10 | const newObject = { ...object }; 11 | 12 | args.forEach((arg) => { 13 | delete newObject[arg]; 14 | }); 15 | 16 | return newObject; 17 | }; 18 | -------------------------------------------------------------------------------- /objects/exercises/06-invoke.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Task description: Write a method that invokes an array method on a specific path 3 | * Expected Result: ({ a: { b: [1, 2, 3] } }, 'a.b', splice, [1, 2]) => [2, 3] 4 | * Task complexity: 3 of 5 5 | * @param {Object} object 6 | * @param {String} path - path in an object to property 7 | * @param {String} func - function to invoke 8 | * @param {Array} [args] - list of args 9 | * @returns {boolean} 10 | */ 11 | export const invoke = (object, path, func, args) => { 12 | throw new Error(`put your solution here ${object} ${path} ${func} ${args}`); 13 | }; 14 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # compiled output 2 | /dist 3 | /tmp 4 | /out-tsc 5 | 6 | # dependencies 7 | /node_modules 8 | 9 | # IDEs and editors 10 | /.idea 11 | .project 12 | .classpath 13 | .c9/ 14 | *.launch 15 | .settings/ 16 | *.sublime-workspace 17 | 18 | # IDE - VSCode 19 | .vscode/* 20 | !.vscode/settings.json 21 | !.vscode/tasks.json 22 | !.vscode/launch.json 23 | !.vscode/extensions.json 24 | 25 | # misc 26 | /.sass-cache 27 | /connect.lock 28 | /coverage 29 | /libpeerconnection.log 30 | npm-debug.log 31 | yarn-error.log 32 | testem.log 33 | /typings 34 | 35 | # System Files 36 | .DS_Store 37 | Thumbs.db 38 | -------------------------------------------------------------------------------- /arrays/solutions/09-chunk.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Task description: Write a method that splits an array into parts of determined size 3 | * Expected Result: ([1, 2, 3, 4, 5], 2) => [[1, 2], [3, 4], [5]] 4 | * Task complexity: 3 of 5 5 | * @param {Array} array - An array of any elements 6 | * @param {number} size - size of chunks 7 | * @returns {Array} 8 | */ 9 | export const chunk = (array, size) => { 10 | const chunkedArr = []; 11 | let index = 0; 12 | while (index < array.length) { 13 | chunkedArr.push(array.slice(index, size + index)); 14 | index += size; 15 | } 16 | return chunkedArr; 17 | }; 18 | -------------------------------------------------------------------------------- /objects/exercises/08-is-equal-deep.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Task description: Write a method that makes a deep compare of two objects 3 | * Expected Result: True if objects are equal, false if objects are different ({ a: 1, b: { c: 1 } }, { a: 1, b: { c: 1 } }) => true 4 | * @param {Object} firstObj - Object with values of primitive data types 5 | * @param {Object} secondObj - Object with values of primitive data types 6 | * @returns {boolean} 7 | */ 8 | export const isEqualDeep = (firstObj, secondObj) => { 9 | throw new Error(`put your solution here ${firstObj} ${secondObj}`); 10 | }; 11 | -------------------------------------------------------------------------------- /objects/exercises/05-is-equal.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Task description: Write a method that makes a shallow compare of two objects 3 | * Expected Result: True if objects are identical, false if objects are different ({ a: 1, b: 1 }, { a: 1, b: 1 }) => true 4 | * Task complexity: 2 of 5 5 | * @param {Object} firstObj - Object with values of primitive data types 6 | * @param {Object} secondObj - Object with values of primitive data types 7 | * @returns {boolean} 8 | */ 9 | export const isEqual = (firstObj, secondObj) => { 10 | throw new Error(`put your solution here ${firstObj} ${secondObj}`); 11 | }; 12 | -------------------------------------------------------------------------------- /objects/solutions/04-is-empty.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Task description: Write a method that makes a shallow check is object empty 3 | * Expected Result: ({}) => true, ({ a: undefined }) => true, ({ a: 1 }) => false 4 | * Empty values: '', null, NaN, undefined 5 | * Task complexity: 2 of 5 6 | * @param {Object} object - Object with values of primitive data types 7 | * @returns {boolean} 8 | */ 9 | export const isEmpty = (object) => { 10 | const objectKeys = Object.keys(object); 11 | if (objectKeys.length === 0) { 12 | return true; 13 | } 14 | 15 | return !objectKeys.filter((key) => object[key] || object[key] === 0 || object[key] === false).length; 16 | }; 17 | -------------------------------------------------------------------------------- /arrays/solutions/07-is-equal.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Task description: Write a method that makes a shallow compare of two arrays and returns true if they are identical. 3 | * Expected Result: ([1, 2, 3], [1, 2, 3]) => true 4 | * Task Complexity: 2 of 5 5 | * @param {Array} firstArray - Array of primitive data types 6 | * @param {Array} secondArray - Array of primitive data types 7 | * @returns {boolean} 8 | */ 9 | export const isEqual = (firstArray, secondArray) => { 10 | if (firstArray.length !== secondArray.length) { 11 | return false; 12 | } 13 | 14 | const compared = firstArray.map((el, id) => secondArray[id] === el); 15 | 16 | return !compared.includes(false); 17 | }; 18 | -------------------------------------------------------------------------------- /arrays/exercises/__tests__/05-without.test.js: -------------------------------------------------------------------------------- 1 | import { without } from '../05-without'; 2 | 3 | describe('without function tests', () => { 4 | it('should return an array without 1 and 2', () => { 5 | const data = [1, 2, 3, 1, 2]; 6 | 7 | expect(without(data, 1, 2)).toEqual([3]); 8 | }); 9 | it('should return an array without "a"', () => { 10 | const data = ['a', 2, 3, 'a', 2]; 11 | 12 | expect(without(data, 'a')).toEqual([2, 3, 2]); 13 | }); 14 | it('should return a new array without listed values', () => { 15 | const data = [1, 2, 3, 1, 2]; 16 | 17 | const result1 = without(data, '1', '2'); 18 | expect(result1 === data).toBe(false); 19 | }); 20 | }); 21 | -------------------------------------------------------------------------------- /arrays/exercises/__tests__/09-chunk.test.js: -------------------------------------------------------------------------------- 1 | import { chunk } from '../09-chunk'; 2 | 3 | describe('chunk function tests', () => { 4 | it('should return an array with chunks sized by 2', () => { 5 | const data = [1, 2, 3, 4, 5]; 6 | 7 | expect(chunk(data, 2)).toEqual([[1, 2], [3, 4], [5]]); 8 | }); 9 | it('should return an array with chunks sized by 3', () => { 10 | const data = [1, 2, 3, 4, 5]; 11 | 12 | expect(chunk(data, 3)).toEqual([[1, 2, 3], [4, 5]]); 13 | }); 14 | it('should return a new chunked array', () => { 15 | const data = [1, 2, 3, 4, 5]; 16 | 17 | const result1 = chunk(data, 2); 18 | expect(result1 === data).toBe(false); 19 | }); 20 | }); 21 | -------------------------------------------------------------------------------- /arrays/solutions/__tests__/09-chunk.test.js: -------------------------------------------------------------------------------- 1 | import { chunk } from '../09-chunk'; 2 | 3 | describe('solution of chunk function tests', () => { 4 | it('should return an array with chunks sized by 2', () => { 5 | const data = [1, 2, 3, 4, 5]; 6 | 7 | expect(chunk(data, 2)).toEqual([[1, 2], [3, 4], [5]]); 8 | }); 9 | it('should return an array with chunks sized by 3', () => { 10 | const data = [1, 2, 3, 4, 5]; 11 | 12 | expect(chunk(data, 3)).toEqual([[1, 2, 3], [4, 5]]); 13 | }); 14 | it('should return a new chunked array', () => { 15 | const data = [1, 2, 3, 4, 5]; 16 | 17 | const result1 = chunk(data, 2); 18 | expect(result1 === data).toBe(false); 19 | }); 20 | }); 21 | -------------------------------------------------------------------------------- /arrays/solutions/10-intersection.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Task description: Write a method that creates an array of unique values that are included in all given arrays 3 | * Expected Result: ([1, 2], [2, 3]) => [2] 4 | * Task complexity: 4 of 5 5 | * @param {?} arrays - Arrays of primitive data types 6 | * @returns {Array} 7 | */ 8 | export const intersection = (...arrays) => { 9 | const result = arrays[0].filter((element) => { 10 | const indexOfElement = arrays[1].indexOf(element); 11 | if (indexOfElement >= 0) { 12 | return element; 13 | } 14 | }); 15 | if (arrays.length > 2) { 16 | intersection(result, ...arrays.slice(2, arrays.length)); 17 | } 18 | return Array.from(new Set(result)); 19 | }; 20 | -------------------------------------------------------------------------------- /objects/solutions/06-invoke.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Task description: Write a method that invokes an array method on a specific path 3 | * Expected Result: ({ a: { b: [1, 2, 3] } }, 'a.b', splice, [1, 2]) => [2, 3] 4 | * Task complexity: 3 of 5 5 | * @param {Object} object 6 | * @param {String} path - path in an object to property 7 | * @param {String} func - function to invoke 8 | * @param {Array} [args] - list of args 9 | * @returns {boolean} 10 | */ 11 | export const invoke = (object, path, func, args) => { 12 | const splittedPath = path.split('.'); 13 | 14 | const target = splittedPath.reduce((acc, key) => { 15 | acc = acc[key] ? acc[key] : object[key]; 16 | return acc; 17 | }, {}); 18 | 19 | return Array.prototype[func].apply(target, args); 20 | }; 21 | -------------------------------------------------------------------------------- /objects/solutions/09-intersection.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Task description: Write a method that finds shallow intersections of objects 3 | * Expected Result: ({ a: 1, b: 2 }, { c: 1, b: 2 }) => { b: 2 } 4 | * @param {Object} firstObj - Object with values of primitive data types 5 | * @param {Object} secondObj - Object with values of primitive data types 6 | * @returns {Object} 7 | */ 8 | export const intersection = (firstObj, secondObj) => { 9 | const firstObjKeys = Object.keys(firstObj); 10 | 11 | return firstObjKeys.reduce((acc = {}, key) => { 12 | if (firstObj[key] === secondObj[key]) { 13 | acc = { 14 | ...acc, 15 | [key]: firstObj[key], 16 | }; 17 | } 18 | 19 | return acc; 20 | }, {}); 21 | }; 22 | -------------------------------------------------------------------------------- /arrays/solutions/06-unique.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Task description: Write a method that returns a duplicate-free array 3 | * Expected Result: Duplicate-free array [1, 2, 3, 1, 2] => [1, 2, 3] 4 | * Task Complexity: 2 of 5 5 | * @param {Array} array - Array of primitive data types 6 | * @returns {Array} 7 | */ 8 | export const unique = (array) => Array.from(new Set(array)); 9 | 10 | /** 11 | * Task description: Write a method that returns a duplicate-free array 12 | * Expected Result: Duplicate-free array [1, 2, 3, 1, 2] => [1, 2, 3] 13 | * Task Complexity: 2 of 5 14 | * @param {Array} array - Array of primitive data types 15 | * @returns {Array} 16 | */ 17 | export const unique2 = (array) => array.filter((element, id) => array.indexOf(element) === id); 18 | -------------------------------------------------------------------------------- /arrays/solutions/02-reverse.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Task description: Write a method that reverts input array 3 | * Expected Result: [1, 2, 3] => [3, 2, 1] 4 | * Task Complexity: 1 of 5 5 | * @param {Array} array - Array of any elements 6 | * @returns {Array} 7 | */ 8 | export const reverse = (array) => { 9 | const reversed = []; 10 | 11 | for (let i = array.length - 1; i >= 0; i -= 1) { 12 | reversed.push(array[i]); 13 | } 14 | 15 | return reversed; 16 | }; 17 | 18 | /** 19 | * Task description: Write a method that reverts input array 20 | * Expected Result: [1, 2, 3] => [3, 2, 1] 21 | * Task Complexity: 1 of 5 22 | * @param {Array} array - Array of any elements 23 | * @returns {Array} 24 | */ 25 | export const reverse2 = (array) => array.map((el, id, givenArr) => givenArr[givenArr.length - id - 1]); 26 | -------------------------------------------------------------------------------- /arrays/exercises/__tests__/02-reverse.test.js: -------------------------------------------------------------------------------- 1 | import { reverse } from '../02-reverse'; 2 | 3 | describe('reverse function tests', () => { 4 | it('[1, 2, 3, 4, 5] -> [5, 4, 3, 2, 1]', () => { 5 | const data = [1, 2, 3, 4, 5]; 6 | 7 | expect(reverse(data)).toEqual([5, 4, 3, 2, 1]); 8 | }); 9 | it('[1, 2, 3, [1, 2]] -> [[1, 2], 3, 2, 1]', () => { 10 | const data = [1, 2, 3, [1, 2]]; 11 | 12 | expect(reverse(data)).toEqual([[1, 2], 3, 2, 1]); 13 | }); 14 | it('[1, 2, 3, { a: 1 }] -> [{ a: 1 }, 3, 2, 1]', () => { 15 | const data = [1, 2, 3, { a: 1 }]; 16 | 17 | expect(reverse(data)).toEqual([{ a: 1 }, 3, 2, 1]); 18 | }); 19 | it('should return a new reversed array', () => { 20 | const data = [1, 2, 3, 4, 5]; 21 | 22 | const result1 = reverse(data); 23 | expect(result1 === data).toBe(false); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /objects/exercises/__tests__/02. make-pairs.test.js: -------------------------------------------------------------------------------- 1 | import { makePairs } from '../02-make-pairs'; 2 | 3 | describe('makePairs function test', () => { 4 | it('should return deep array', () => { 5 | const data = { 6 | a: 1, 7 | b: 2, 8 | c: [3, 4], 9 | }; 10 | 11 | expect(makePairs(data)).toEqual([['a', 1], ['b', 2], ['c', [3, 4]]]); 12 | }); 13 | it('should return deep array', () => { 14 | const data = { 15 | a: 1, 16 | b: undefined, 17 | c: { 18 | a: 1, 19 | }, 20 | }; 21 | 22 | expect(makePairs(data)).toEqual([['a', 1], ['b', undefined], ['c', { a: 1 }]]); 23 | }); 24 | it('should return deep array', () => { 25 | const data = { 26 | a: null, 27 | b: NaN, 28 | c: '3', 29 | }; 30 | 31 | expect(makePairs(data)).toEqual([['a', null], ['b', NaN], ['c', '3']]); 32 | }); 33 | }); 34 | -------------------------------------------------------------------------------- /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "env": { 3 | "browser": true, 4 | "es6": true, 5 | "jest": true 6 | }, 7 | "extends": [ 8 | "airbnb-base" 9 | ], 10 | "globals": { 11 | "Atomics": "readonly", 12 | "SharedArrayBuffer": "readonly" 13 | }, 14 | "parserOptions": { 15 | "ecmaVersion": 2018, 16 | "sourceType": "module" 17 | }, 18 | "rules": { 19 | "guard-for-in": "off", 20 | "no-restricted-syntax": "off", 21 | "no-prototype-builtins": "off", 22 | "import/prefer-default-export": "off", 23 | "no-use-before-define": "off", 24 | "prefer-rest-params": "off", 25 | "max-len": ["error", { 26 | "code": 120, 27 | "comments": 140 28 | }], 29 | "prefer-destructuring": "off", 30 | "array-callback-return": "off", 31 | "consistent-return": "off", 32 | "no-param-reassign": "off", 33 | "default-param-last": "off" 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /arrays/exercises/__tests__/06-unique.test.js: -------------------------------------------------------------------------------- 1 | import { unique } from '../06-unique'; 2 | 3 | describe('unique function tests', () => { 4 | it('should return a duplicate-free array [1, 2, 3]', () => { 5 | const data = [1, 2, 3, 1, 2]; 6 | 7 | expect(unique(data)).toEqual([1, 2, 3]); 8 | }); 9 | it('should return a duplicate-free array ["a", 2, 3]', () => { 10 | const data = ['a', 2, 3, 'a', 2]; 11 | 12 | expect(unique(data)).toEqual(['a', 2, 3]); 13 | }); 14 | it('should return a duplicate-free array [1, undefined, 2, 3]', () => { 15 | const data = [1, undefined, 2, 3, 1, 2, undefined]; 16 | 17 | expect(unique(data)).toEqual([1, undefined, 2, 3]); 18 | }); 19 | it('should return a new duplicate-free array', () => { 20 | const data = [1, 2, 3, 1, 2]; 21 | 22 | const result1 = unique(data); 23 | expect(result1 === data).toBe(false); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /arrays/solutions/__tests__/05-without.test.js: -------------------------------------------------------------------------------- 1 | import { without, without2 } from '../05-without'; 2 | 3 | describe('solution of without function tests', () => { 4 | it('should return an array without 1 and 2', () => { 5 | const data = [1, 2, 3, 1, 2]; 6 | 7 | expect(without(data, 1, 2)).toEqual([3]); 8 | expect(without2(data, 1, 2)).toEqual([3]); 9 | }); 10 | it('should return an array without "a"', () => { 11 | const data = ['a', 2, 3, 'a', 2]; 12 | 13 | expect(without(data, 'a')).toEqual([2, 3, 2]); 14 | expect(without2(data, 'a')).toEqual([2, 3, 2]); 15 | }); 16 | it('should return a new array without listed values', () => { 17 | const data = [1, 2, 3, 1, 2]; 18 | 19 | const result1 = without(data, '1', '2'); 20 | const result2 = without2(data, '1', '2'); 21 | expect(result1 === data).toBe(false); 22 | expect(result2 === data).toBe(false); 23 | }); 24 | }); 25 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "javascript-exercises", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "jest", 8 | "testObjects": "jest /objects/exercises/", 9 | "testObjectsSolutions": "jest /objects/solutions/", 10 | "testArrays": "jest /arrays/exercises/", 11 | "testArraysSolutions": "jest /arrays/solutions/", 12 | "lint": "eslint \"*/**\"" 13 | }, 14 | "jest": { 15 | "testEnvironment": "node", 16 | "testMatch": [ 17 | "/**/*.(test|spec).{js,jsx,ts,tsx}" 18 | ], 19 | "moduleFileExtensions": [ 20 | "js", 21 | "html" 22 | ] 23 | }, 24 | "author": "", 25 | "license": "ISC", 26 | "devDependencies": { 27 | "@babel/core": "^7.16.5", 28 | "@babel/preset-env": "^7.16.5", 29 | "babel-jest": "^27.4.5", 30 | "eslint": "^8.5.0", 31 | "eslint-config-airbnb-base": "^15.0.0", 32 | "eslint-plugin-import": "^2.25.3", 33 | "jest": "^27.4.5" 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /arrays/exercises/__tests__/07-is-equal.test.js: -------------------------------------------------------------------------------- 1 | import { isEqual } from '../07-is-equal'; 2 | 3 | describe('isEqual function tests', () => { 4 | it('should return true, arrays are identical', () => { 5 | const data = [1, 2, 3]; 6 | const data2 = [1, 2, 3]; 7 | 8 | expect(isEqual(data, data2)).toEqual(true); 9 | }); 10 | it('should return false, different values', () => { 11 | const data = [1, 2, 3]; 12 | const data2 = [1, 2, 4]; 13 | 14 | expect(isEqual(data, data2)).toEqual(false); 15 | expect(isEqual(data2, data)).toEqual(false); 16 | }); 17 | it('should return false, different length', () => { 18 | const data = [1, 2, 3]; 19 | const data2 = [1, 2]; 20 | 21 | expect(isEqual(data, data2)).toEqual(false); 22 | expect(isEqual(data2, data)).toEqual(false); 23 | }); 24 | it('should return false, different order', () => { 25 | const data = [1, 3, 2]; 26 | const data2 = [1, 2, 3]; 27 | 28 | expect(isEqual(data, data2)).toEqual(false); 29 | expect(isEqual(data2, data)).toEqual(false); 30 | }); 31 | }); 32 | -------------------------------------------------------------------------------- /objects/exercises/__tests__/06-invoke.test.js: -------------------------------------------------------------------------------- 1 | import { invoke } from '../06-invoke'; 2 | 3 | describe('invoke function tests', () => { 4 | it('pass array method splice', () => { 5 | const data = { 6 | a: { 7 | b: [1, 2, 3], 8 | }, 9 | }; 10 | 11 | expect(invoke(data, 'a.b', 'splice', [1, 3])).toEqual([2, 3]); 12 | expect(data).toEqual({ 13 | a: { 14 | b: [1], 15 | }, 16 | }); 17 | }); 18 | it('pass array method pop', () => { 19 | const data = { 20 | a: { 21 | b: [1, 2, 3], 22 | }, 23 | }; 24 | 25 | expect(invoke(data, 'a.b', 'pop')).toBe(3); 26 | expect(data).toEqual({ 27 | a: { 28 | b: [1, 2], 29 | }, 30 | }); 31 | }); 32 | it('pass array method pop', () => { 33 | const data = { 34 | a: { 35 | b: [1, 2, 3], 36 | }, 37 | }; 38 | 39 | expect(invoke(data, 'a.b', 'slice', [0, 1])).toEqual([1]); 40 | expect(data).toEqual({ 41 | a: { 42 | b: [1, 2, 3], 43 | }, 44 | }); 45 | }); 46 | }); 47 | -------------------------------------------------------------------------------- /arrays/solutions/__tests__/07-is-equal.test.js: -------------------------------------------------------------------------------- 1 | import { isEqual } from '../07-is-equal'; 2 | 3 | describe('solution of isEqual function tests', () => { 4 | it('should return true, arrays are identical', () => { 5 | const data = [1, 2, 3]; 6 | const data2 = [1, 2, 3]; 7 | 8 | expect(isEqual(data, data2)).toEqual(true); 9 | }); 10 | it('should return false, different values', () => { 11 | const data = [1, 2, 3]; 12 | const data2 = [1, 2, 4]; 13 | 14 | expect(isEqual(data, data2)).toEqual(false); 15 | expect(isEqual(data2, data)).toEqual(false); 16 | }); 17 | it('should return false, different length', () => { 18 | const data = [1, 2, 3]; 19 | const data2 = [1, 2]; 20 | 21 | expect(isEqual(data, data2)).toEqual(false); 22 | expect(isEqual(data2, data)).toEqual(false); 23 | }); 24 | it('should return false, different order', () => { 25 | const data = [1, 3, 2]; 26 | const data2 = [1, 2, 3]; 27 | 28 | expect(isEqual(data, data2)).toEqual(false); 29 | expect(isEqual(data2, data)).toEqual(false); 30 | }); 31 | }); 32 | -------------------------------------------------------------------------------- /objects/solutions/__tests__/06-invoke.test.js: -------------------------------------------------------------------------------- 1 | import { invoke } from '../06-invoke'; 2 | 3 | describe('solution of invoke function tests', () => { 4 | it('pass array method splice', () => { 5 | const data = { 6 | a: { 7 | b: [1, 2, 3], 8 | }, 9 | }; 10 | 11 | expect(invoke(data, 'a.b', 'splice', [1, 3])).toEqual([2, 3]); 12 | expect(data).toEqual({ 13 | a: { 14 | b: [1], 15 | }, 16 | }); 17 | }); 18 | it('pass array method pop', () => { 19 | const data = { 20 | a: { 21 | b: [1, 2, 3], 22 | }, 23 | }; 24 | 25 | expect(invoke(data, 'a.b', 'pop')).toBe(3); 26 | expect(data).toEqual({ 27 | a: { 28 | b: [1, 2], 29 | }, 30 | }); 31 | }); 32 | it('pass array method pop', () => { 33 | const data = { 34 | a: { 35 | b: [1, 2, 3], 36 | }, 37 | }; 38 | 39 | expect(invoke(data, 'a.b', 'slice', [0, 1])).toEqual([1]); 40 | expect(data).toEqual({ 41 | a: { 42 | b: [1, 2, 3], 43 | }, 44 | }); 45 | }); 46 | }); 47 | -------------------------------------------------------------------------------- /objects/exercises/__tests__/09-intersection.test.js: -------------------------------------------------------------------------------- 1 | import { intersection } from '../09-intersection'; 2 | 3 | describe('intersection function tests', () => { 4 | it('should return { b: 2 }', () => { 5 | const firstObject = { 6 | a: 1, 7 | b: 2, 8 | }; 9 | const secondObject = { 10 | b: 2, 11 | c: 3, 12 | }; 13 | 14 | expect(intersection(firstObject, secondObject)).toEqual({ b: 2 }); 15 | }); 16 | it('should return { b: 2, c: 3 } 2', () => { 17 | const firstObject = { 18 | a: 1, 19 | b: 2, 20 | c: 3, 21 | }; 22 | const secondObject = { 23 | b: 2, 24 | c: 3, 25 | e: null, 26 | }; 27 | 28 | expect(intersection(firstObject, secondObject)).toEqual({ b: 2, c: 3 }); 29 | }); 30 | it('should return empty object, no intersections', () => { 31 | const firstObject = { 32 | a: 1, 33 | b: 3, 34 | }; 35 | const secondObject = { 36 | b: 2, 37 | c: 3, 38 | }; 39 | 40 | expect(intersection(firstObject, secondObject)).toEqual({}); 41 | }); 42 | }); 43 | -------------------------------------------------------------------------------- /objects/solutions/__tests__/09-intersection.test.js: -------------------------------------------------------------------------------- 1 | import { intersection } from '../09-intersection'; 2 | 3 | describe('solution of intersection function tests', () => { 4 | it('should return { b: 2 }', () => { 5 | const firstObject = { 6 | a: 1, 7 | b: 2, 8 | }; 9 | const secondObject = { 10 | b: 2, 11 | c: 3, 12 | }; 13 | 14 | expect(intersection(firstObject, secondObject)).toEqual({ b: 2 }); 15 | }); 16 | it('should return { b: 2, c: 3 } 2', () => { 17 | const firstObject = { 18 | a: 1, 19 | b: 2, 20 | c: 3, 21 | }; 22 | const secondObject = { 23 | b: 2, 24 | c: 3, 25 | e: null, 26 | }; 27 | 28 | expect(intersection(firstObject, secondObject)).toEqual({ b: 2, c: 3 }); 29 | }); 30 | it('should return empty object, no intersections', () => { 31 | const firstObject = { 32 | a: 1, 33 | b: 3, 34 | }; 35 | const secondObject = { 36 | b: 2, 37 | c: 3, 38 | }; 39 | 40 | expect(intersection(firstObject, secondObject)).toEqual({}); 41 | }); 42 | }); 43 | -------------------------------------------------------------------------------- /arrays/solutions/__tests__/02-reverse.test.js: -------------------------------------------------------------------------------- 1 | import { reverse, reverse2 } from '../02-reverse'; 2 | 3 | describe('solution of reverse function tests', () => { 4 | it('[1, 2, 3, 4, 5] -> [5, 4, 3, 2, 1]', () => { 5 | const data = [1, 2, 3, 4, 5]; 6 | 7 | expect(reverse(data)).toEqual([5, 4, 3, 2, 1]); 8 | expect(reverse2(data)).toEqual([5, 4, 3, 2, 1]); 9 | }); 10 | it('[1, 2, 3, [1, 2]] -> [[1, 2], 3, 2, 1]', () => { 11 | const data = [1, 2, 3, [1, 2]]; 12 | 13 | expect(reverse(data)).toEqual([[1, 2], 3, 2, 1]); 14 | expect(reverse2(data)).toEqual([[1, 2], 3, 2, 1]); 15 | }); 16 | it('[1, 2, 3, { a: 1 }] -> [{ a: 1 }, 3, 2, 1]', () => { 17 | const data = [1, 2, 3, { a: 1 }]; 18 | 19 | expect(reverse(data)).toEqual([{ a: 1 }, 3, 2, 1]); 20 | expect(reverse2(data)).toEqual([{ a: 1 }, 3, 2, 1]); 21 | }); 22 | it('should return a new reversed array', () => { 23 | const data = [1, 2, 3, 4, 5]; 24 | 25 | const result1 = reverse(data); 26 | const result2 = reverse(data); 27 | expect(result1 === data).toBe(false); 28 | expect(result2 === data).toBe(false); 29 | }); 30 | }); 31 | -------------------------------------------------------------------------------- /objects/exercises/__tests__/05-is-equal.test.js: -------------------------------------------------------------------------------- 1 | import { isEqual } from '../05-is-equal'; 2 | 3 | describe('isEqual function tests', () => { 4 | const data = { 5 | a: 1, 6 | b: 2, 7 | }; 8 | const data2 = { 9 | a: 1, 10 | b: 2, 11 | }; 12 | const data3 = { 13 | a: 1, 14 | b: 3, 15 | }; 16 | const data4 = { 17 | a: 1, 18 | c: 2, 19 | }; 20 | const data5 = { 21 | a: 1, 22 | }; 23 | const data6 = { 24 | e: undefined, 25 | }; 26 | 27 | it('should return true, objects are equal', () => { 28 | expect(isEqual({}, {})).toBe(true); 29 | expect(isEqual(data, data2)).toBe(true); 30 | }); 31 | it('should return false, b: 2 !== b: 3', () => { 32 | expect(isEqual(data, data3)).toBe(false); 33 | }); 34 | it('should return false, b: 2 !== c: 2', () => { 35 | expect(isEqual(data, data4)).toBe(false); 36 | }); 37 | it('should return false, lacking "b" property', () => { 38 | expect(isEqual(data, data5)).toBe(false); 39 | }); 40 | it('should return false, objects completely different', () => { 41 | expect(isEqual(data, data6)).toBe(false); 42 | }); 43 | }); 44 | -------------------------------------------------------------------------------- /arrays/solutions/05-without.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Task description: Write a method that returns an array without listed values 3 | * Expected Result: [1, 2, 3, 1, 2] without 1, 2 => [3] 4 | * Task Complexity: 2 of 5 5 | * @param {Array} array - Array of primitive data types 6 | * @param {?} args list of values to remove 7 | * @returns {Array} 8 | */ 9 | export const without = (array, ...args) => { 10 | let filteredArray = [...array]; 11 | 12 | for (let i = 0; i < args.length; i += 1) { 13 | filteredArray = filteredArray.filter((el) => el !== args[i]); 14 | } 15 | 16 | return filteredArray; 17 | }; 18 | 19 | /** 20 | * Task description: Write a method that returns an array without listed values 21 | * Expected Result: [1, 2, 3, 1, 2] without 1, 2 => [3] 22 | * Task Complexity: 2 of 5 23 | * @param {Array} array - Array of primitive data types 24 | * @returns {Array} 25 | */ 26 | export function without2(array) { 27 | let filteredArray = [...array]; 28 | 29 | for (let i = 1; i < arguments.length; i += 1) { 30 | filteredArray = filteredArray.filter((el) => el !== arguments[i]); 31 | } 32 | 33 | return filteredArray; 34 | } 35 | -------------------------------------------------------------------------------- /arrays/solutions/__tests__/06-unique.test.js: -------------------------------------------------------------------------------- 1 | import { unique, unique2 } from '../06-unique'; 2 | 3 | describe('solution of unique function tests', () => { 4 | it('should return a duplicate-free array [1, 2, 3]', () => { 5 | const data = [1, 2, 3, 1, 2]; 6 | 7 | expect(unique(data)).toEqual([1, 2, 3]); 8 | expect(unique2(data)).toEqual([1, 2, 3]); 9 | }); 10 | it('should return a duplicate-free array ["a", 2, 3]', () => { 11 | const data = ['a', 2, 3, 'a', 2]; 12 | 13 | expect(unique(data)).toEqual(['a', 2, 3]); 14 | expect(unique2(data)).toEqual(['a', 2, 3]); 15 | }); 16 | it('should return a duplicate-free array [1, undefined, 2, 3]', () => { 17 | const data = [1, undefined, 2, 3, 1, 2, undefined]; 18 | 19 | expect(unique(data)).toEqual([1, undefined, 2, 3]); 20 | expect(unique2(data)).toEqual([1, undefined, 2, 3]); 21 | }); 22 | it('should return a new duplicate-free array', () => { 23 | const data = [1, 2, 3, 1, 2]; 24 | 25 | const result1 = unique(data); 26 | const result2 = unique2(data); 27 | expect(result1 === data).toBe(false); 28 | expect(result2 === data).toBe(false); 29 | }); 30 | }); 31 | -------------------------------------------------------------------------------- /arrays/exercises/__tests__/10-intersection.test.js: -------------------------------------------------------------------------------- 1 | import { intersection } from '../10-intersection'; 2 | 3 | describe('intersection function tests', () => { 4 | it('should return [3]', () => { 5 | const data = [1, 2, 3]; 6 | const data2 = [3, 4, 5]; 7 | 8 | expect(intersection(data, data2)).toEqual([3]); 9 | }); 10 | it('should return [3, 4]', () => { 11 | const data = [1, 2, 3, 4]; 12 | const data2 = [3, 4, 5]; 13 | 14 | expect(intersection(data, data2)).toEqual([3, 4]); 15 | }); 16 | it('should return [1, 2]', () => { 17 | const data = [1, 2]; 18 | const data2 = [1, 2, 3, 4, 5]; 19 | 20 | expect(intersection(data, data2)).toEqual([1, 2]); 21 | }); 22 | it('should return [1, 2]', () => { 23 | const data = [1, 2]; 24 | const data2 = [1, 2, 3, 4, 5]; 25 | const data3 = [1, 2, 3, 4, 5, 6]; 26 | 27 | expect(intersection(data, data2, data3)).toEqual([1, 2]); 28 | }); 29 | it('should return an empty array', () => { 30 | const data = [7, 8]; 31 | const data2 = [1, 2, 3, 4, 5]; 32 | const data3 = [1, 2, 3, 4, 5, 6]; 33 | 34 | expect(intersection(data, data2, data3)).toEqual([]); 35 | }); 36 | }); 37 | -------------------------------------------------------------------------------- /arrays/solutions/__tests__/10-intersection.test.js: -------------------------------------------------------------------------------- 1 | import { intersection } from '../10-intersection'; 2 | 3 | describe('solution of intersection function tests', () => { 4 | it('should return [3]', () => { 5 | const data = [1, 2, 3]; 6 | const data2 = [3, 4, 5]; 7 | 8 | expect(intersection(data, data2)).toEqual([3]); 9 | }); 10 | it('should return [3, 4]', () => { 11 | const data = [1, 2, 3, 4]; 12 | const data2 = [3, 4, 5]; 13 | 14 | expect(intersection(data, data2)).toEqual([3, 4]); 15 | }); 16 | it('should return [1, 2]', () => { 17 | const data = [1, 2]; 18 | const data2 = [1, 2, 3, 4, 5]; 19 | 20 | expect(intersection(data, data2)).toEqual([1, 2]); 21 | }); 22 | it('should return [1, 2]', () => { 23 | const data = [1, 2]; 24 | const data2 = [1, 2, 3, 4, 5]; 25 | const data3 = [1, 2, 3, 4, 5, 6]; 26 | 27 | expect(intersection(data, data2, data3)).toEqual([1, 2]); 28 | }); 29 | it('should return an empty array', () => { 30 | const data = [7, 8]; 31 | const data2 = [1, 2, 3, 4, 5]; 32 | const data3 = [1, 2, 3, 4, 5, 6]; 33 | 34 | expect(intersection(data, data2, data3)).toEqual([]); 35 | }); 36 | }); 37 | -------------------------------------------------------------------------------- /objects/exercises/__tests__/01-is-plain-object.test.js: -------------------------------------------------------------------------------- 1 | import { isPlainObject } from '../01-is-plain-object'; 2 | 3 | describe('isPlainObject function tests', () => { 4 | it('{} is plain object === true', () => { 5 | expect(isPlainObject({})).toBe(true); 6 | }); 7 | it('{ a: 1 } is plain object === true', () => { 8 | expect(isPlainObject({ a: 1 })).toBe(true); 9 | }); 10 | it('[1, 2, 3] is not plain object === false', () => { 11 | expect(isPlainObject([1, 2, 3])).toBe(false); 12 | }); 13 | it('null is not plain object === false', () => { 14 | expect(isPlainObject(null)).toBe(false); 15 | }); 16 | it('undefined is not plain object === false', () => { 17 | expect(isPlainObject(undefined)).toBe(false); 18 | }); 19 | it('NaN is not plain object === false', () => { 20 | expect(isPlainObject(NaN)).toBe(false); 21 | }); 22 | it('1 is not plain object === false', () => { 23 | expect(isPlainObject(1)).toBe(false); 24 | }); 25 | it('"1" is not plain object === false', () => { 26 | expect(isPlainObject('1')).toBe(false); 27 | }); 28 | it('() => {} is not plain object === false', () => { 29 | expect(isPlainObject(() => {})).toBe(false); 30 | }); 31 | it('class is not plain object === false', () => { 32 | expect(isPlainObject(class Test {})).toBe(false); 33 | }); 34 | }); 35 | -------------------------------------------------------------------------------- /objects/exercises/__tests__/03-without.test.js: -------------------------------------------------------------------------------- 1 | import { without } from '../03-without'; 2 | 3 | describe('without function test', () => { 4 | it('should return new object without listed properties', () => { 5 | const data = { 6 | a: 1, 7 | b: 2, 8 | c: [3, 4], 9 | }; 10 | 11 | expect(without(data, 'a', 'c')).toEqual({ b: 2 }); 12 | }); 13 | it('should return new object without listed properties', () => { 14 | const data = { 15 | property: 'a', 16 | property2: 2, 17 | property3: undefined, 18 | property4: null, 19 | property5: { 20 | property: 'a1', 21 | property2: 2, 22 | }, 23 | }; 24 | 25 | expect(without(data, 'property3', 'property4', 'property5')).toEqual({ 26 | property: 'a', 27 | property2: 2, 28 | }); 29 | }); 30 | it('should return new object without listed properties', () => { 31 | const data = { 32 | name: 'UserName', 33 | age: 28, 34 | }; 35 | 36 | expect(without(data, 'age')).toEqual({ name: 'UserName' }); 37 | }); 38 | it('should check that method returns new object', () => { 39 | const data = { 40 | a: 1, 41 | b: 2, 42 | c: [3, 4], 43 | }; 44 | 45 | const result = without(data, 'a', 'c'); 46 | expect(result).not.toEqual(data); 47 | }); 48 | }); 49 | -------------------------------------------------------------------------------- /objects/solutions/__tests__/01-is-plain-object.test.js: -------------------------------------------------------------------------------- 1 | import { isPlainObject } from '../01-is-plain-object'; 2 | 3 | describe('solution of isPlainObject function tests', () => { 4 | it('{} is plain object === true', () => { 5 | expect(isPlainObject({})).toBe(true); 6 | }); 7 | it('{ a: 1 } is plain object === true', () => { 8 | expect(isPlainObject({ a: 1 })).toBe(true); 9 | }); 10 | it('[1, 2, 3] is not plain object === false', () => { 11 | expect(isPlainObject([1, 2, 3])).toBe(false); 12 | }); 13 | it('null is not plain object === false', () => { 14 | expect(isPlainObject(null)).toBe(false); 15 | }); 16 | it('undefined is not plain object === false', () => { 17 | expect(isPlainObject(undefined)).toBe(false); 18 | }); 19 | it('NaN is not plain object === false', () => { 20 | expect(isPlainObject(NaN)).toBe(false); 21 | }); 22 | it('1 is not plain object === false', () => { 23 | expect(isPlainObject(1)).toBe(false); 24 | }); 25 | it('"1" is not plain object === false', () => { 26 | expect(isPlainObject('1')).toBe(false); 27 | }); 28 | it('() => {} is not plain object === false', () => { 29 | expect(isPlainObject(() => {})).toBe(false); 30 | }); 31 | it('class is not plain object === false', () => { 32 | expect(isPlainObject(class Test {})).toBe(false); 33 | }); 34 | }); 35 | -------------------------------------------------------------------------------- /objects/solutions/__tests__/03-without.test.js: -------------------------------------------------------------------------------- 1 | import { without } from '../03-without'; 2 | 3 | describe('solution of without function test', () => { 4 | it('should return new object without listed properties', () => { 5 | const data = { 6 | a: 1, 7 | b: 2, 8 | c: [3, 4], 9 | }; 10 | 11 | expect(without(data, 'a', 'c')).toEqual({ b: 2 }); 12 | }); 13 | it('should return new object without listed properties', () => { 14 | const data = { 15 | property: 'a', 16 | property2: 2, 17 | property3: undefined, 18 | property4: null, 19 | property5: { 20 | property: 'a1', 21 | property2: 2, 22 | }, 23 | }; 24 | 25 | expect(without(data, 'property3', 'property4', 'property5')).toEqual({ 26 | property: 'a', 27 | property2: 2, 28 | }); 29 | }); 30 | it('should return new object without listed properties', () => { 31 | const data = { 32 | name: 'UserName', 33 | age: 28, 34 | }; 35 | 36 | expect(without(data, 'age')).toEqual({ name: 'UserName' }); 37 | }); 38 | it('should check that method returns new object', () => { 39 | const data = { 40 | a: 1, 41 | b: 2, 42 | c: [3, 4], 43 | }; 44 | 45 | const result = without(data, 'a', 'c'); 46 | expect(result).not.toEqual(data); 47 | }); 48 | }); 49 | -------------------------------------------------------------------------------- /objects/solutions/02-make-pairs.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Task description: Write a method that returns a deep array like [[key, value]] 3 | * Expected Result: ({ a: 1, b: 2 }) => [['a', 1], ['b', 2]] 4 | * Task complexity: 1 of 5 5 | * @param {Object} object - Any object to transform into array 6 | * @returns {Array} - a deep array 7 | */ 8 | export const makePairs = (object) => Object.entries(object); 9 | 10 | /** 11 | * Task description: Write a method that returns a deep array like [[key, value]] 12 | * Expected Result: ({ a: 1, b: 2 }) => [['a', 1], ['b', 2]] 13 | * Task complexity: 1 of 5 14 | * @param {Object} object - Any object to transform into array 15 | * @returns {Array} - a deep array 16 | */ 17 | export const makePairs2 = (object) => Object.keys(object).map((el) => [el, object[el]]); 18 | 19 | /** 20 | * Task description: Write a method that returns a deep array like [[key, value]] 21 | * Expected Result: ({ a: 1, b: 2 }) => [['a', 1], ['b', 2]] 22 | * Task complexity: 1 of 5 23 | * @param {Object} object - Any object to transform into array 24 | * @returns {Array} - a deep array 25 | */ 26 | export const makePairs3 = (object) => { 27 | const result = []; 28 | 29 | for (const prop in object) { 30 | if (object.hasOwnProperty(prop)) { 31 | result.push([prop, object[prop]]); 32 | } 33 | } 34 | 35 | return result; 36 | }; 37 | -------------------------------------------------------------------------------- /objects/solutions/__tests__/02. make-pairs.test.js: -------------------------------------------------------------------------------- 1 | import { makePairs, makePairs2, makePairs3 } from '../02-make-pairs'; 2 | 3 | describe('solution of makePairs function test', () => { 4 | it('should return deep array', () => { 5 | const data = { 6 | a: 1, 7 | b: 2, 8 | c: [3, 4], 9 | }; 10 | 11 | expect(makePairs(data)).toEqual([['a', 1], ['b', 2], ['c', [3, 4]]]); 12 | expect(makePairs2(data)).toEqual([['a', 1], ['b', 2], ['c', [3, 4]]]); 13 | expect(makePairs3(data)).toEqual([['a', 1], ['b', 2], ['c', [3, 4]]]); 14 | }); 15 | it('should return deep array', () => { 16 | const data = { 17 | a: 1, 18 | b: undefined, 19 | c: { 20 | a: 1, 21 | }, 22 | }; 23 | 24 | expect(makePairs(data)).toEqual([['a', 1], ['b', undefined], ['c', { a: 1 }]]); 25 | expect(makePairs2(data)).toEqual([['a', 1], ['b', undefined], ['c', { a: 1 }]]); 26 | expect(makePairs3(data)).toEqual([['a', 1], ['b', undefined], ['c', { a: 1 }]]); 27 | }); 28 | it('should return deep array', () => { 29 | const data = { 30 | a: null, 31 | b: NaN, 32 | c: '3', 33 | }; 34 | 35 | expect(makePairs(data)).toEqual([['a', null], ['b', NaN], ['c', '3']]); 36 | expect(makePairs2(data)).toEqual([['a', null], ['b', NaN], ['c', '3']]); 37 | expect(makePairs3(data)).toEqual([['a', null], ['b', NaN], ['c', '3']]); 38 | }); 39 | }); 40 | -------------------------------------------------------------------------------- /objects/solutions/__tests__/05-is-equal.test.js: -------------------------------------------------------------------------------- 1 | import { isEqual, isEqual2 } from '../05-is-equal'; 2 | 3 | describe('solution of isEqual function tests', () => { 4 | const data = { 5 | a: 1, 6 | b: 2, 7 | }; 8 | const data2 = { 9 | a: 1, 10 | b: 2, 11 | }; 12 | const data3 = { 13 | a: 1, 14 | b: 3, 15 | }; 16 | const data4 = { 17 | a: 1, 18 | c: 2, 19 | }; 20 | const data5 = { 21 | a: 1, 22 | }; 23 | const data6 = { 24 | e: undefined, 25 | }; 26 | 27 | it('should return true, objects are equal', () => { 28 | expect(isEqual({}, {})).toBe(true); 29 | expect(isEqual(data, data2)).toBe(true); 30 | expect(isEqual2(data, data2)).toBe(true); 31 | }); 32 | it('should return false, b: 2 !== b: 3', () => { 33 | expect(isEqual(data, data3)).toBe(false); 34 | expect(isEqual2(data, data3)).toBe(false); 35 | }); 36 | it('should return false, b: 2 !== c: 2', () => { 37 | expect(isEqual(data, data4)).toBe(false); 38 | expect(isEqual2(data, data4)).toBe(false); 39 | }); 40 | it('should return false, lacking "b" property', () => { 41 | expect(isEqual(data, data5)).toBe(false); 42 | expect(isEqual2(data, data5)).toBe(false); 43 | }); 44 | it('should return false, objects completely different', () => { 45 | expect(isEqual(data, data6)).toBe(false); 46 | expect(isEqual2(data, data6)).toBe(false); 47 | }); 48 | }); 49 | -------------------------------------------------------------------------------- /objects/solutions/10-intersection-deep.js: -------------------------------------------------------------------------------- 1 | import { isEqualDeep } from './08-is-equal-deep'; 2 | 3 | /** 4 | * Task description: Write a method that finds all intersections of objects 5 | * Expected Result: ({ a: 1, b: { c: 3 } }, { c: 1, b: { c: 3 } }) => { b: { c: 3 } } 6 | * @param {Object} firstObj - Object with values of any data types 7 | * @param {Object} secondObj - Object with values of any data types 8 | * @returns {Object} 9 | */ 10 | export const intersectionDeep = (firstObj, secondObj) => { 11 | const firstObjKeys = Object.keys(firstObj); 12 | 13 | return firstObjKeys.reduce((acc = {}, key) => { 14 | if (firstObj[key] === secondObj[key]) { 15 | acc = { 16 | ...acc, 17 | [key]: firstObj[key], 18 | }; 19 | } 20 | if (Array.isArray(firstObj[key]) && Array.isArray(secondObj[key])) { 21 | const isEqualArrays = isEqualDeep(firstObj[key], secondObj[key]); 22 | 23 | if (isEqualArrays) { 24 | acc = { 25 | ...acc, 26 | [key]: firstObj[key], 27 | }; 28 | } 29 | } else if (typeof firstObj[key] === 'object' && typeof secondObj[key] === 'object') { 30 | const hasIntersection = intersectionDeep(firstObj[key], secondObj[key]); 31 | 32 | if (Object.keys(hasIntersection).length !== 0) { 33 | acc = { 34 | ...acc, 35 | [key]: hasIntersection, 36 | }; 37 | } 38 | } 39 | return acc; 40 | }, {}); 41 | }; 42 | -------------------------------------------------------------------------------- /objects/exercises/__tests__/04-is-empty.test.js: -------------------------------------------------------------------------------- 1 | import { isEmpty } from '../04-is-empty'; 2 | 3 | describe('isEmpty function test', () => { 4 | it('should return false, objects has primitive values', () => { 5 | const data = { a: 0 }; 6 | const data2 = { a: 1 }; 7 | const data3 = { a: '1' }; 8 | const data4 = { a: true }; 9 | const data5 = { a: false }; 10 | const data6 = { a: 1, b: undefined }; 11 | 12 | expect(isEmpty(data)).toBe(false); 13 | expect(isEmpty(data2)).toBe(false); 14 | expect(isEmpty(data3)).toBe(false); 15 | expect(isEmpty(data4)).toBe(false); 16 | expect(isEmpty(data5)).toBe(false); 17 | expect(isEmpty(data6)).toBe(false); 18 | }); 19 | it('should return true, {} is empty', () => { 20 | const data = {}; 21 | 22 | expect(isEmpty(data)).toBe(true); 23 | }); 24 | it('should return false, shallow check, so [] and {} counts as not empty', () => { 25 | const data = { a: {} }; 26 | const data2 = { a: [] }; 27 | 28 | expect(isEmpty(data)).toBe(false); 29 | expect(isEmpty(data2)).toBe(false); 30 | }); 31 | it('should return true, objects with null, NaN, undefined, empty string, [], {}', () => { 32 | const data = { a: null }; 33 | const data2 = { a: NaN }; 34 | const data3 = { a: undefined }; 35 | const data4 = { a: '' }; 36 | 37 | expect(isEmpty(data)).toBe(true); 38 | expect(isEmpty(data2)).toBe(true); 39 | expect(isEmpty(data3)).toBe(true); 40 | expect(isEmpty(data4)).toBe(true); 41 | }); 42 | }); 43 | -------------------------------------------------------------------------------- /objects/solutions/__tests__/04-is-empty.test.js: -------------------------------------------------------------------------------- 1 | import { isEmpty } from '../04-is-empty'; 2 | 3 | describe('solution of isEmpty function test', () => { 4 | it('should return false, objects has primitive values', () => { 5 | const data = { a: 0 }; 6 | const data2 = { a: 1 }; 7 | const data3 = { a: '1' }; 8 | const data4 = { a: true }; 9 | const data5 = { a: false }; 10 | const data6 = { a: 1, b: undefined }; 11 | 12 | expect(isEmpty(data)).toBe(false); 13 | expect(isEmpty(data2)).toBe(false); 14 | expect(isEmpty(data3)).toBe(false); 15 | expect(isEmpty(data4)).toBe(false); 16 | expect(isEmpty(data5)).toBe(false); 17 | expect(isEmpty(data6)).toBe(false); 18 | }); 19 | it('should return true, {} is empty', () => { 20 | const data = {}; 21 | 22 | expect(isEmpty(data)).toBe(true); 23 | }); 24 | it('should return false, shallow check, so [] and {} counts as not empty', () => { 25 | const data = { a: {} }; 26 | const data2 = { a: [] }; 27 | 28 | expect(isEmpty(data)).toBe(false); 29 | expect(isEmpty(data2)).toBe(false); 30 | }); 31 | it('should return true, objects with null, NaN, undefined, empty string, [], {}', () => { 32 | const data = { a: null }; 33 | const data2 = { a: NaN }; 34 | const data3 = { a: undefined }; 35 | const data4 = { a: '' }; 36 | 37 | expect(isEmpty(data)).toBe(true); 38 | expect(isEmpty(data2)).toBe(true); 39 | expect(isEmpty(data3)).toBe(true); 40 | expect(isEmpty(data4)).toBe(true); 41 | }); 42 | }); 43 | -------------------------------------------------------------------------------- /objects/solutions/05-is-equal.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Task description: Write a method that makes a shallow compare of two objects 3 | * Expected Result: True if objects are identical, false if objects are different ({ a: 1, b: 1 }, { a: 1, b: 1 }) => true 4 | * Task complexity: 2 of 5 5 | * @param {Object} firstObj - Object with values of primitive data types 6 | * @param {Object} secondObj - Object with values of primitive data types 7 | * @returns {boolean} 8 | */ 9 | export const isEqual = (firstObj, secondObj) => { 10 | const firstObjKeys = Object.keys(firstObj); 11 | const secondObjKeys = Object.keys(secondObj); 12 | 13 | if (firstObjKeys.length !== secondObjKeys.length) { 14 | return false; 15 | } 16 | 17 | return !firstObjKeys.filter((key) => firstObj[key] !== secondObj[key]).length; 18 | }; 19 | 20 | /** 21 | * Task description: Write a method that makes a shallow compare of two objects 22 | * Expected Result: True if objects are identical, false if objects are different ({ a: 1, b: 1 }, { a: 1, b: 1 }) => true 23 | * Task complexity: 2 of 5 24 | * @param {Object} firstObj - Object with values of primitive data types 25 | * @param {Object} secondObj - Object with values of primitive data types 26 | * @returns {boolean} 27 | */ 28 | export const isEqual2 = (firstObj, secondObj) => { 29 | const firstObjKeys = Object.keys(firstObj); 30 | const secondObjKeys = Object.keys(secondObj); 31 | 32 | if (firstObjKeys.length !== secondObjKeys.length) { 33 | return false; 34 | } 35 | 36 | for (const prop in firstObj) { 37 | if (firstObj.hasOwnProperty(prop) && (firstObj[prop] !== secondObj[prop])) { 38 | return false; 39 | } 40 | } 41 | 42 | return true; 43 | }; 44 | -------------------------------------------------------------------------------- /objects/solutions/07-is-empty-deep.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Task description: Write a method that makes a deep check is an object empty 3 | * Empty values: '', null, NaN, undefined, [], {} 4 | * Expected Result: ({}) => true, ({ a: { b: undefined } }) => true, ({ a: { b: [] } }) => true 5 | * Task complexity: 3 of 5 6 | * @param {?} element - Object with values of any data types 7 | * @returns {boolean} 8 | */ 9 | export const isEmptyDeep = (element) => { 10 | if (element === null) { 11 | return true; 12 | } 13 | if (Array.isArray(element)) { 14 | if (element.length === 0) { 15 | return true; 16 | } 17 | 18 | let result; 19 | for (let i = 0; i < element.length; i += 1) { 20 | if (typeof element[i] === 'boolean' || (typeof element[i] === 'number' && !Number.isNaN(element[i])) 21 | || (typeof element[i] === 'string' && element[i] !== '')) { 22 | result = false; 23 | break; 24 | } 25 | if (Array.isArray(element[i]) || (typeof element[i] === 'object' && element[i] !== null)) { 26 | result = isEmptyDeep(element[i]); 27 | break; 28 | } 29 | 30 | result = true; 31 | } 32 | 33 | return result; 34 | } 35 | if (typeof element === 'object') { 36 | const objectKeys = Object.keys(element); 37 | if (objectKeys.length === 0) { 38 | return true; 39 | } 40 | 41 | let result; 42 | for (let i = 0; i < objectKeys.length; i += 1) { 43 | const value = element[objectKeys[i]]; 44 | 45 | if (typeof value === 'boolean' || (typeof value === 'number' && !Number.isNaN(value)) 46 | || (typeof value === 'string' && value !== '')) { 47 | result = false; 48 | break; 49 | } 50 | if (Array.isArray(value) || (typeof value === 'object' && value !== null)) { 51 | result = isEmptyDeep(value); 52 | break; 53 | } 54 | 55 | result = true; 56 | } 57 | 58 | return result; 59 | } 60 | }; 61 | -------------------------------------------------------------------------------- /objects/solutions/08-is-equal-deep.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Task description: Write a method that makes a deep compare of two objects 3 | * Expected Result: True if objects are equal, false if objects are different ({ a: 1, b: { c: 1 } }, { a: 1, b: { c: 1 } }) => true 4 | * @param {Object} firstObj - Object of any values 5 | * @param {Object} secondObj - Object of any values 6 | * @returns {boolean} 7 | */ 8 | export const isEqualDeep = (firstObj, secondObj) => { 9 | const firstObjKeys = Object.keys(firstObj); 10 | const secondObjKeys = Object.keys(secondObj); 11 | 12 | if (firstObjKeys.length === 0 && secondObjKeys.length === 0) { 13 | return true; 14 | } 15 | 16 | const compareList = firstObjKeys.map((key) => { 17 | const valueOfFirstObject = firstObj[key]; 18 | const valueOfSecondObject = secondObj[key]; 19 | if ((Number.isNaN(valueOfFirstObject) && Number.isNaN(valueOfSecondObject)) 20 | || (valueOfFirstObject === null && valueOfSecondObject === null)) { 21 | return true; 22 | } 23 | if (valueOfFirstObject === valueOfSecondObject) { 24 | return true; 25 | } 26 | if (Array.isArray(valueOfFirstObject) && Array.isArray(valueOfSecondObject)) { 27 | return isArraysEqualDeep(valueOfFirstObject, valueOfSecondObject); 28 | } 29 | if (typeof valueOfFirstObject === 'object' && typeof valueOfSecondObject === 'object') { 30 | return isEqualDeep(valueOfFirstObject, valueOfSecondObject); 31 | } 32 | 33 | return false; 34 | }); 35 | 36 | return !compareList.includes(false) && !compareList.includes(undefined); 37 | }; 38 | 39 | const isArraysEqualDeep = (firstArray, secondArray) => { 40 | if (firstArray.length !== secondArray.length) { 41 | return false; 42 | } 43 | 44 | const compared = firstArray.map((el, id) => { 45 | if (Array.isArray(el) && Array.isArray(secondArray[id])) { 46 | return isArraysEqualDeep(el, secondArray[id]); 47 | } 48 | if (typeof el === 'object' && typeof secondArray[id] === 'object') { 49 | return isEqualDeep(el, secondArray[id]); 50 | } 51 | 52 | return secondArray[id] === el; 53 | }); 54 | 55 | return !compared.includes(false); 56 | }; 57 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # Javascript practice 2 | I prepared javascript exercises, which I hope will help you to improve your coding skills. 3 | I do not affirm my solutions are the best ways to solve each of the exercises, but I believe they could help you to find some new ideas if you stuck. 4 | 5 | ## Prerequisites 6 | 7 | `npm i` to install jest and lint 8 | 9 | ## Exercises with arrays 10 | 11 | To run check your solutions use `npm run testArrays`.
12 | Also, you can check mine by running `npm run testArraysSolutions`. 13 | 14 | #### List of tasks 15 | 1. fill - Write a method that creates a new array with given values. 16 | 2. reverse - Write a method that reverts input array. 17 | 3. compact - Write a method that clears array from all unnecessary elements, like false, undefined, empty strings, zero, null. 18 | 4. fromPairs - Write a method that returns an object composed of key-value pairs. 19 | 5. without - Write a method that returns an array without listed values. 20 | 6. unique - Write a method that returns a duplicate-free array. 21 | 7. isEqual - Write a method that makes a shallow compare of two arrays and returns true if they are identical. 22 | 8. flatten - Write a method that turns a deep array into a plain array. 23 | 9. chunk - Write a method that splits an array into parts of determined size. 24 | 10. intersection - Write a method that creates an array of unique values that are included in all given arrays. 25 | 26 | ## Exercises with objects 27 | 28 | To run check your solutions use `npm run testObjects`.
29 | Also, you can check mine by running `npm run testObjectsSolutions`. 30 | 31 | #### List of tasks 32 | 1. isPlainObject - Write a method that verifies argument is a plain object, not an array or null 33 | 2. makePairs - Write a method that returns a deep array like [[key, value]] 34 | 3. without - Write a method that returns new object without provided properties 35 | 4. isEmpty - Write a method that makes a shallow check is object empty 36 | 5. isEqual - Write a method that makes a shallow compare of two objects 37 | 6. invoke - Write a method that invokes an array method on a specific path 38 | 7. isEmptyDeep - Write a method that makes a deep check is an object empty 39 | 8. isEqualDeep - Write a method that makes a deep compare of two objects 40 | 9. intersection - Write a method that finds shallow intersections of objects 41 | 10. intersectionDeep - Write a method that finds all intersections of objects 42 | 43 | -------------------------------------------------------------------------------- /objects/exercises/__tests__/10-intersection-deep.test.js: -------------------------------------------------------------------------------- 1 | import { intersectionDeep } from '../10-intersection-deep'; 2 | 3 | describe('intersectionDeep function tests', () => { 4 | it('should return { b: 2 }', () => { 5 | const firstObject = { 6 | a: 1, 7 | b: 2, 8 | }; 9 | const secondObject = { 10 | b: 2, 11 | c: 3, 12 | }; 13 | 14 | expect(intersectionDeep(firstObject, secondObject)).toEqual({ b: 2 }); 15 | }); 16 | it('should return { b: 2, c: 3 }', () => { 17 | const firstObject = { 18 | a: 1, 19 | b: 2, 20 | c: 3, 21 | }; 22 | const secondObject = { 23 | b: 2, 24 | c: 3, 25 | e: null, 26 | }; 27 | 28 | expect(intersectionDeep(firstObject, secondObject)).toEqual({ b: 2, c: 3 }); 29 | }); 30 | it('should return { b: { c: 2 } }', () => { 31 | const firstObject = { 32 | a: 1, 33 | b: { 34 | c: 2, 35 | }, 36 | e: 3, 37 | }; 38 | const secondObject = { 39 | b: { 40 | c: 2, 41 | }, 42 | e: 4, 43 | f: null, 44 | }; 45 | 46 | expect(intersectionDeep(firstObject, secondObject)).toEqual({ b: { c: 2 } }); 47 | }); 48 | it('should return { b: { c: [1, 2] } }', () => { 49 | const firstObject = { 50 | a: 1, 51 | b: { 52 | c: [1, 2], 53 | }, 54 | e: 3, 55 | }; 56 | const secondObject = { 57 | b: { 58 | c: [1, 2], 59 | }, 60 | e: 4, 61 | f: null, 62 | }; 63 | 64 | expect(intersectionDeep(firstObject, secondObject)).toEqual({ b: { c: [1, 2] } }); 65 | }); 66 | it('should return {}, first array deep', () => { 67 | const firstObject = { 68 | a: 1, 69 | b: { 70 | c: [[1], 2], 71 | }, 72 | e: 3, 73 | }; 74 | const secondObject = { 75 | b: { 76 | c: [1, 2], 77 | }, 78 | e: 4, 79 | f: null, 80 | }; 81 | 82 | expect(intersectionDeep(firstObject, secondObject)).toEqual({}); 83 | }); 84 | it('should return { b: { c: [[1], 2] }}', () => { 85 | const firstObject = { 86 | a: 1, 87 | b: { 88 | c: [[1], 2], 89 | }, 90 | e: 3, 91 | }; 92 | const secondObject = { 93 | b: { 94 | c: [[1], 2], 95 | }, 96 | e: 4, 97 | f: null, 98 | }; 99 | 100 | expect(intersectionDeep(firstObject, secondObject)).toEqual({ b: { c: [[1], 2] } }); 101 | }); 102 | it('should return { b: { c: [{ a: 1 }, 2] }}', () => { 103 | const firstObject = { 104 | a: 1, 105 | b: { 106 | c: [{ a: 1 }, 2], 107 | }, 108 | e: 3, 109 | }; 110 | const secondObject = { 111 | b: { 112 | c: [{ a: 1 }, 2], 113 | }, 114 | e: 4, 115 | f: null, 116 | }; 117 | 118 | expect(intersectionDeep(firstObject, secondObject)).toEqual({ b: { c: [{ a: 1 }, 2] } }); 119 | }); 120 | it('should return empty object, no intersections', () => { 121 | const firstObject = { 122 | a: 1, 123 | b: 3, 124 | }; 125 | const secondObject = { 126 | b: 2, 127 | c: 3, 128 | }; 129 | 130 | expect(intersectionDeep(firstObject, secondObject)).toEqual({}); 131 | }); 132 | }); 133 | -------------------------------------------------------------------------------- /objects/solutions/__tests__/10-intersection-deep.test.js: -------------------------------------------------------------------------------- 1 | import { intersectionDeep } from '../10-intersection-deep'; 2 | 3 | describe('solution of intersectionDeep function tests', () => { 4 | it('should return { b: 2 }', () => { 5 | const firstObject = { 6 | a: 1, 7 | b: 2, 8 | }; 9 | const secondObject = { 10 | b: 2, 11 | c: 3, 12 | }; 13 | 14 | expect(intersectionDeep(firstObject, secondObject)).toEqual({ b: 2 }); 15 | }); 16 | it('should return { b: 2, c: 3 }', () => { 17 | const firstObject = { 18 | a: 1, 19 | b: 2, 20 | c: 3, 21 | }; 22 | const secondObject = { 23 | b: 2, 24 | c: 3, 25 | e: null, 26 | }; 27 | 28 | expect(intersectionDeep(firstObject, secondObject)).toEqual({ b: 2, c: 3 }); 29 | }); 30 | it('should return { b: { c: 2 } }', () => { 31 | const firstObject = { 32 | a: 1, 33 | b: { 34 | c: 2, 35 | }, 36 | e: 3, 37 | }; 38 | const secondObject = { 39 | b: { 40 | c: 2, 41 | }, 42 | e: 4, 43 | f: null, 44 | }; 45 | 46 | expect(intersectionDeep(firstObject, secondObject)).toEqual({ b: { c: 2 } }); 47 | }); 48 | it('should return { b: { c: [1, 2] } }', () => { 49 | const firstObject = { 50 | a: 1, 51 | b: { 52 | c: [1, 2], 53 | }, 54 | e: 3, 55 | }; 56 | const secondObject = { 57 | b: { 58 | c: [1, 2], 59 | }, 60 | e: 4, 61 | f: null, 62 | }; 63 | 64 | expect(intersectionDeep(firstObject, secondObject)).toEqual({ b: { c: [1, 2] } }); 65 | }); 66 | it('should return {}, first array deep', () => { 67 | const firstObject = { 68 | a: 1, 69 | b: { 70 | c: [[1], 2], 71 | }, 72 | e: 3, 73 | }; 74 | const secondObject = { 75 | b: { 76 | c: [1, 2], 77 | }, 78 | e: 4, 79 | f: null, 80 | }; 81 | 82 | expect(intersectionDeep(firstObject, secondObject)).toEqual({}); 83 | }); 84 | it('should return { b: { c: [[1], 2] }}', () => { 85 | const firstObject = { 86 | a: 1, 87 | b: { 88 | c: [[1], 2], 89 | }, 90 | e: 3, 91 | }; 92 | const secondObject = { 93 | b: { 94 | c: [[1], 2], 95 | }, 96 | e: 4, 97 | f: null, 98 | }; 99 | 100 | expect(intersectionDeep(firstObject, secondObject)).toEqual({ b: { c: [[1], 2] } }); 101 | }); 102 | it('should return { b: { c: [{ a: 1 }, 2] }}', () => { 103 | const firstObject = { 104 | a: 1, 105 | b: { 106 | c: [{ a: 1 }, 2], 107 | }, 108 | e: 3, 109 | }; 110 | const secondObject = { 111 | b: { 112 | c: [{ a: 1 }, 2], 113 | }, 114 | e: 4, 115 | f: null, 116 | }; 117 | 118 | expect(intersectionDeep(firstObject, secondObject)).toEqual({ b: { c: [{ a: 1 }, 2] } }); 119 | }); 120 | it('should return empty object, no intersections', () => { 121 | const firstObject = { 122 | a: 1, 123 | b: 3, 124 | }; 125 | const secondObject = { 126 | b: 2, 127 | c: 3, 128 | }; 129 | 130 | expect(intersectionDeep(firstObject, secondObject)).toEqual({}); 131 | }); 132 | }); 133 | -------------------------------------------------------------------------------- /objects/exercises/__tests__/08-is-equal-deep.test.js: -------------------------------------------------------------------------------- 1 | import { isEqualDeep } from '../08-is-equal-deep'; 2 | 3 | describe('isEqualDeep function tests', () => { 4 | it('should return true, empty objects are equal', () => { 5 | expect(isEqualDeep({}, {})).toBe(true); 6 | }); 7 | it('should return true, plain objects are equal', () => { 8 | const data = { 9 | a: 1, 10 | b: 2, 11 | c: 3, 12 | e: '4', 13 | }; 14 | const data2 = { 15 | a: 1, 16 | b: 2, 17 | c: 3, 18 | e: '4', 19 | }; 20 | 21 | expect(isEqualDeep(data, data2)).toBe(true); 22 | }); 23 | it('should return true, objects with empty values are equal', () => { 24 | const data = { 25 | a: { 26 | b: {}, 27 | c: 1, 28 | }, 29 | }; 30 | const data2 = { 31 | a: { 32 | b: {}, 33 | c: 1, 34 | }, 35 | }; 36 | 37 | expect(isEqualDeep(data, data2)).toBe(true); 38 | }); 39 | it('should return true, objects with nested values are equal', () => { 40 | const data = { 41 | a: { 42 | b: 1, 43 | c: 2, 44 | }, 45 | b: { 46 | c: { 47 | d: 2, 48 | e: 3, 49 | }, 50 | }, 51 | }; 52 | const data2 = { 53 | a: { 54 | b: 1, 55 | c: 2, 56 | }, 57 | b: { 58 | c: { 59 | d: 2, 60 | e: 3, 61 | }, 62 | }, 63 | }; 64 | 65 | expect(isEqualDeep(data, data2)).toBe(true); 66 | }); 67 | it('should return true, objects with empty arrays are equal', () => { 68 | const data = { 69 | a: { 70 | b: [], 71 | c: 1, 72 | }, 73 | }; 74 | const data2 = { 75 | a: { 76 | b: [], 77 | c: 1, 78 | }, 79 | }; 80 | 81 | expect(isEqualDeep(data, data2)).toBe(true); 82 | }); 83 | it('should return true, objects with equal arrays are equal', () => { 84 | const data = { 85 | a: { 86 | b: [1, 2, 3], 87 | }, 88 | }; 89 | const data2 = { 90 | a: { 91 | b: [1, 2, 3], 92 | }, 93 | }; 94 | 95 | expect(isEqualDeep(data, data2)).toBe(true); 96 | }); 97 | it('should return false, objects with different arrays', () => { 98 | const data = { 99 | a: { 100 | b: [1, 2, 3], 101 | }, 102 | }; 103 | const data2 = { 104 | a: { 105 | b: [1, 3, 2], 106 | }, 107 | }; 108 | 109 | expect(isEqualDeep(data, data2)).toBe(false); 110 | }); 111 | it('should return true, values with arrays are equal', () => { 112 | const data = { 113 | a: { 114 | b: [1, 2, 3, [1, 2, 3]], 115 | }, 116 | }; 117 | const data2 = { 118 | a: { 119 | b: [1, 2, 3, [1, 2, 3]], 120 | }, 121 | }; 122 | 123 | expect(isEqualDeep(data, data2)).toBe(true); 124 | }); 125 | it('should return false, values with arrays are different', () => { 126 | const data = { 127 | a: { 128 | b: [1, 2, 3, [2, 8, 2]], 129 | }, 130 | }; 131 | const data2 = { 132 | a: { 133 | b: [1, 2, 3, [2, 2, 8]], 134 | }, 135 | }; 136 | 137 | expect(isEqualDeep(data, data2)).toBe(false); 138 | }); 139 | it('should return true, values with objects are equal', () => { 140 | const data = { 141 | a: { 142 | b: [1, 2, 3, { a: 1 }], 143 | }, 144 | }; 145 | const data2 = { 146 | a: { 147 | b: [1, 2, 3, { a: 1 }], 148 | }, 149 | }; 150 | 151 | expect(isEqualDeep(data, data2)).toBe(true); 152 | }); 153 | it('should return true, objects are equal', () => { 154 | const data = { 155 | a: { 156 | b: [1, 2, 3], 157 | }, 158 | b: null, 159 | c: undefined, 160 | e: { 161 | a: NaN, 162 | }, 163 | f: { 164 | a: 1, 165 | }, 166 | }; 167 | const data2 = { 168 | a: { 169 | b: [1, 2, 3], 170 | }, 171 | b: null, 172 | c: undefined, 173 | e: { 174 | a: NaN, 175 | }, 176 | f: { 177 | a: 1, 178 | }, 179 | }; 180 | 181 | expect(isEqualDeep(data, data2)).toBe(true); 182 | }); 183 | it('should return false, different values in the objects', () => { 184 | const data = { 185 | a: { 186 | b: { 187 | a: 1, 188 | b: 2, 189 | }, 190 | }, 191 | }; 192 | const data2 = { 193 | a: { 194 | b: { 195 | a: 2, 196 | b: 3, 197 | }, 198 | }, 199 | }; 200 | 201 | expect(isEqualDeep(data, data2)).toBe(false); 202 | }); 203 | it('should return false, different keys in the objects', () => { 204 | const data = { 205 | a: { 206 | b: { 207 | a: 1, 208 | b: 2, 209 | }, 210 | }, 211 | }; 212 | const data2 = { 213 | a: { 214 | b: { 215 | c: 1, 216 | d: 2, 217 | }, 218 | }, 219 | }; 220 | 221 | expect(isEqualDeep(data, data2)).toBe(false); 222 | }); 223 | it('should return false, different length of the arrays', () => { 224 | const data = { 225 | a: { 226 | b: [1, 2, 3], 227 | }, 228 | }; 229 | const data2 = { 230 | a: { 231 | b: [1, 2], 232 | }, 233 | }; 234 | 235 | expect(isEqualDeep(data, data2)).toBe(false); 236 | }); 237 | it('should return false, different values in the arrays', () => { 238 | const data = { 239 | a: { 240 | b: [1, 2, 3], 241 | }, 242 | }; 243 | const data2 = { 244 | a: { 245 | b: [1, 2, 4], 246 | }, 247 | }; 248 | 249 | expect(isEqualDeep(data, data2)).toBe(false); 250 | }); 251 | }); 252 | -------------------------------------------------------------------------------- /objects/solutions/__tests__/08-is-equal-deep.test.js: -------------------------------------------------------------------------------- 1 | import { isEqualDeep } from '../08-is-equal-deep'; 2 | 3 | describe('solution of isEqualDeep function tests', () => { 4 | it('should return true, empty objects are equal', () => { 5 | expect(isEqualDeep({}, {})).toBe(true); 6 | }); 7 | it('should return true, plain objects are equal', () => { 8 | const data = { 9 | a: 1, 10 | b: 2, 11 | c: 3, 12 | e: '4', 13 | }; 14 | const data2 = { 15 | a: 1, 16 | b: 2, 17 | c: 3, 18 | e: '4', 19 | }; 20 | 21 | expect(isEqualDeep(data, data2)).toBe(true); 22 | }); 23 | it('should return true, objects with empty values are equal', () => { 24 | const data = { 25 | a: { 26 | b: {}, 27 | c: 1, 28 | }, 29 | }; 30 | const data2 = { 31 | a: { 32 | b: {}, 33 | c: 1, 34 | }, 35 | }; 36 | 37 | expect(isEqualDeep(data, data2)).toBe(true); 38 | }); 39 | it('should return true, objects with nested values are equal', () => { 40 | const data = { 41 | a: { 42 | b: 1, 43 | c: 2, 44 | }, 45 | b: { 46 | c: { 47 | d: 2, 48 | e: 3, 49 | }, 50 | }, 51 | }; 52 | const data2 = { 53 | a: { 54 | b: 1, 55 | c: 2, 56 | }, 57 | b: { 58 | c: { 59 | d: 2, 60 | e: 3, 61 | }, 62 | }, 63 | }; 64 | 65 | expect(isEqualDeep(data, data2)).toBe(true); 66 | }); 67 | it('should return true, objects with empty arrays are equal', () => { 68 | const data = { 69 | a: { 70 | b: [], 71 | c: 1, 72 | }, 73 | }; 74 | const data2 = { 75 | a: { 76 | b: [], 77 | c: 1, 78 | }, 79 | }; 80 | 81 | expect(isEqualDeep(data, data2)).toBe(true); 82 | }); 83 | it('should return true, objects with equal arrays are equal', () => { 84 | const data = { 85 | a: { 86 | b: [1, 2, 3], 87 | }, 88 | }; 89 | const data2 = { 90 | a: { 91 | b: [1, 2, 3], 92 | }, 93 | }; 94 | 95 | expect(isEqualDeep(data, data2)).toBe(true); 96 | }); 97 | it('should return false, objects with different arrays', () => { 98 | const data = { 99 | a: { 100 | b: [1, 2, 3], 101 | }, 102 | }; 103 | const data2 = { 104 | a: { 105 | b: [1, 3, 2], 106 | }, 107 | }; 108 | 109 | expect(isEqualDeep(data, data2)).toBe(false); 110 | }); 111 | it('should return true, values with arrays are equal', () => { 112 | const data = { 113 | a: { 114 | b: [1, 2, 3, [1, 2, 3]], 115 | }, 116 | }; 117 | const data2 = { 118 | a: { 119 | b: [1, 2, 3, [1, 2, 3]], 120 | }, 121 | }; 122 | 123 | expect(isEqualDeep(data, data2)).toBe(true); 124 | }); 125 | it('should return false, values with arrays are different', () => { 126 | const data = { 127 | a: { 128 | b: [1, 2, 3, [2, 8, 2]], 129 | }, 130 | }; 131 | const data2 = { 132 | a: { 133 | b: [1, 2, 3, [2, 2, 8]], 134 | }, 135 | }; 136 | 137 | expect(isEqualDeep(data, data2)).toBe(false); 138 | }); 139 | it('should return true, values with objects are equal', () => { 140 | const data = { 141 | a: { 142 | b: [1, 2, 3, { a: 1 }], 143 | }, 144 | }; 145 | const data2 = { 146 | a: { 147 | b: [1, 2, 3, { a: 1 }], 148 | }, 149 | }; 150 | 151 | expect(isEqualDeep(data, data2)).toBe(true); 152 | }); 153 | it('should return true, objects are equal', () => { 154 | const data = { 155 | a: { 156 | b: [1, 2, 3], 157 | }, 158 | b: null, 159 | c: undefined, 160 | e: { 161 | a: NaN, 162 | }, 163 | f: { 164 | a: 1, 165 | }, 166 | }; 167 | const data2 = { 168 | a: { 169 | b: [1, 2, 3], 170 | }, 171 | b: null, 172 | c: undefined, 173 | e: { 174 | a: NaN, 175 | }, 176 | f: { 177 | a: 1, 178 | }, 179 | }; 180 | 181 | expect(isEqualDeep(data, data2)).toBe(true); 182 | }); 183 | it('should return false, different values in the objects', () => { 184 | const data = { 185 | a: { 186 | b: { 187 | a: 1, 188 | b: 2, 189 | }, 190 | }, 191 | }; 192 | const data2 = { 193 | a: { 194 | b: { 195 | a: 2, 196 | b: 3, 197 | }, 198 | }, 199 | }; 200 | 201 | expect(isEqualDeep(data, data2)).toBe(false); 202 | }); 203 | it('should return false, different keys in the objects', () => { 204 | const data = { 205 | a: { 206 | b: { 207 | a: 1, 208 | b: 2, 209 | }, 210 | }, 211 | }; 212 | const data2 = { 213 | a: { 214 | b: { 215 | c: 1, 216 | d: 2, 217 | }, 218 | }, 219 | }; 220 | 221 | expect(isEqualDeep(data, data2)).toBe(false); 222 | }); 223 | it('should return false, different length of the arrays', () => { 224 | const data = { 225 | a: { 226 | b: [1, 2, 3], 227 | }, 228 | }; 229 | const data2 = { 230 | a: { 231 | b: [1, 2], 232 | }, 233 | }; 234 | 235 | expect(isEqualDeep(data, data2)).toBe(false); 236 | }); 237 | it('should return false, different values in the arrays', () => { 238 | const data = { 239 | a: { 240 | b: [1, 2, 3], 241 | }, 242 | }; 243 | const data2 = { 244 | a: { 245 | b: [1, 2, 4], 246 | }, 247 | }; 248 | 249 | expect(isEqualDeep(data, data2)).toBe(false); 250 | }); 251 | }); 252 | -------------------------------------------------------------------------------- /objects/exercises/__tests__/07-is-empty-deep.test.js: -------------------------------------------------------------------------------- 1 | import { isEmptyDeep } from '../07-is-empty-deep'; 2 | 3 | describe('isEmptyDeep function test', () => { 4 | it('should return false, objects has primitive values', () => { 5 | const data = { a: 0 }; 6 | const data2 = { a: 1 }; 7 | const data3 = { a: '1' }; 8 | const data4 = { a: true }; 9 | const data5 = { a: false }; 10 | const data6 = { a: 1, b: undefined }; 11 | 12 | expect(isEmptyDeep(data)).toBe(false); 13 | expect(isEmptyDeep(data2)).toBe(false); 14 | expect(isEmptyDeep(data3)).toBe(false); 15 | expect(isEmptyDeep(data4)).toBe(false); 16 | expect(isEmptyDeep(data5)).toBe(false); 17 | expect(isEmptyDeep(data6)).toBe(false); 18 | }); 19 | it('should return false, deep objects has primitive values', () => { 20 | const deepObject = { a: { b: 0 } }; 21 | const deepObject2 = { a: { b: 1 } }; 22 | const deepObject3 = { a: { b: '1' } }; 23 | const deepObject4 = { a: { b: true } }; 24 | const deepObject5 = { a: { b: false } }; 25 | const deepObject6 = { a: { b: undefined, c: 1 } }; 26 | 27 | expect(isEmptyDeep(deepObject)).toBe(false); 28 | expect(isEmptyDeep(deepObject2)).toBe(false); 29 | expect(isEmptyDeep(deepObject3)).toBe(false); 30 | expect(isEmptyDeep(deepObject4)).toBe(false); 31 | expect(isEmptyDeep(deepObject5)).toBe(false); 32 | expect(isEmptyDeep(deepObject6)).toBe(false); 33 | }); 34 | it('should return true, {} is empty', () => { 35 | const data = {}; 36 | 37 | expect(isEmptyDeep(data)).toBe(true); 38 | }); 39 | it('should return true, objects with null, NaN, undefined, empty string, [], {}', () => { 40 | const data = { a: null }; 41 | const data2 = { a: NaN }; 42 | const data3 = { a: undefined }; 43 | const data4 = { a: '' }; 44 | const data5 = { a: {} }; 45 | const data6 = { a: [] }; 46 | 47 | expect(isEmptyDeep(data)).toBe(true); 48 | expect(isEmptyDeep(data2)).toBe(true); 49 | expect(isEmptyDeep(data3)).toBe(true); 50 | expect(isEmptyDeep(data4)).toBe(true); 51 | expect(isEmptyDeep(data5)).toBe(true); 52 | expect(isEmptyDeep(data6)).toBe(true); 53 | }); 54 | it('should return true, objects with child object null, NaN, undefined, empty string, [], {}', () => { 55 | const data = { a: { b: null } }; 56 | const data2 = { a: { b: NaN } }; 57 | const data3 = { a: { b: undefined } }; 58 | const data4 = { a: { b: '' } }; 59 | const data5 = { a: { b: {} } }; 60 | const data6 = { a: { b: [] } }; 61 | 62 | expect(isEmptyDeep(data)).toBe(true); 63 | expect(isEmptyDeep(data2)).toBe(true); 64 | expect(isEmptyDeep(data3)).toBe(true); 65 | expect(isEmptyDeep(data4)).toBe(true); 66 | expect(isEmptyDeep(data5)).toBe(true); 67 | expect(isEmptyDeep(data6)).toBe(true); 68 | }); 69 | it('should return false, objects has arrays with primitive values ', () => { 70 | const data = { a: [0] }; 71 | const data2 = { a: [1] }; 72 | const data3 = { a: ['1'] }; 73 | const data4 = { a: [false] }; 74 | const data5 = { a: [true] }; 75 | const data6 = { a: [undefined, 1] }; 76 | const data7 = { a: [null, '1'] }; 77 | const data8 = { a: [NaN, true] }; 78 | 79 | expect(isEmptyDeep(data)).toBe(false); 80 | expect(isEmptyDeep(data2)).toBe(false); 81 | expect(isEmptyDeep(data3)).toBe(false); 82 | expect(isEmptyDeep(data4)).toBe(false); 83 | expect(isEmptyDeep(data5)).toBe(false); 84 | expect(isEmptyDeep(data6)).toBe(false); 85 | expect(isEmptyDeep(data7)).toBe(false); 86 | expect(isEmptyDeep(data8)).toBe(false); 87 | }); 88 | it('should return false, objects has deep arrays with values ', () => { 89 | const data = { a: [[0]] }; 90 | const data2 = { a: [[1]] }; 91 | const data3 = { a: [['1']] }; 92 | const data4 = { a: [[false]] }; 93 | const data5 = { a: [[true]] }; 94 | const data6 = { a: [[undefined, 1]] }; 95 | const data7 = { a: [[null, '1']] }; 96 | const data8 = { a: [[NaN, true]] }; 97 | const data9 = { a: [[0], undefined] }; 98 | const data10 = { a: [{ a: 1 }] }; 99 | const data11 = { a: [{ a: [1] }] }; 100 | 101 | expect(isEmptyDeep(data)).toBe(false); 102 | expect(isEmptyDeep(data2)).toBe(false); 103 | expect(isEmptyDeep(data3)).toBe(false); 104 | expect(isEmptyDeep(data4)).toBe(false); 105 | expect(isEmptyDeep(data5)).toBe(false); 106 | expect(isEmptyDeep(data6)).toBe(false); 107 | expect(isEmptyDeep(data7)).toBe(false); 108 | expect(isEmptyDeep(data8)).toBe(false); 109 | expect(isEmptyDeep(data9)).toBe(false); 110 | expect(isEmptyDeep(data10)).toBe(false); 111 | expect(isEmptyDeep(data11)).toBe(false); 112 | }); 113 | it('should return true, objects has arrays with NaN, null, undefined, [], {}', () => { 114 | const data = { a: [undefined] }; 115 | const data2 = { a: [''] }; 116 | const data3 = { a: [null] }; 117 | const data4 = { a: [NaN] }; 118 | const data5 = { a: [[]] }; 119 | const data6 = { a: [{}] }; 120 | const data7 = { a: [{ a: undefined }] }; 121 | const data8 = { a: [{ a: [] }] }; 122 | 123 | expect(isEmptyDeep(data)).toBe(true); 124 | expect(isEmptyDeep(data2)).toBe(true); 125 | expect(isEmptyDeep(data3)).toBe(true); 126 | expect(isEmptyDeep(data4)).toBe(true); 127 | expect(isEmptyDeep(data5)).toBe(true); 128 | expect(isEmptyDeep(data6)).toBe(true); 129 | expect(isEmptyDeep(data7)).toBe(true); 130 | expect(isEmptyDeep(data8)).toBe(true); 131 | }); 132 | it('should return true, objects has deep arrays with NaN, null, undefined, [], {}', () => { 133 | const data = { a: [[undefined]] }; 134 | const data2 = { a: [['']] }; 135 | const data3 = { a: [[null]] }; 136 | const data4 = { a: [[NaN]] }; 137 | const data5 = { a: [[[]]] }; 138 | const data6 = { a: [[{}]] }; 139 | const data7 = { a: [[{ a: null }]] }; 140 | const data8 = { a: [[{ a: [''] }]] }; 141 | 142 | expect(isEmptyDeep(data)).toBe(true); 143 | expect(isEmptyDeep(data2)).toBe(true); 144 | expect(isEmptyDeep(data3)).toBe(true); 145 | expect(isEmptyDeep(data4)).toBe(true); 146 | expect(isEmptyDeep(data5)).toBe(true); 147 | expect(isEmptyDeep(data6)).toBe(true); 148 | expect(isEmptyDeep(data7)).toBe(true); 149 | expect(isEmptyDeep(data8)).toBe(true); 150 | }); 151 | }); 152 | -------------------------------------------------------------------------------- /objects/solutions/__tests__/07-is-empty-deep.test.js: -------------------------------------------------------------------------------- 1 | import { isEmptyDeep } from '../07-is-empty-deep'; 2 | 3 | describe('solution of isEmptyDeep function test', () => { 4 | it('should return false, objects has primitive values', () => { 5 | const data = { a: 0 }; 6 | const data2 = { a: 1 }; 7 | const data3 = { a: '1' }; 8 | const data4 = { a: true }; 9 | const data5 = { a: false }; 10 | const data6 = { a: 1, b: undefined }; 11 | 12 | expect(isEmptyDeep(data)).toBe(false); 13 | expect(isEmptyDeep(data2)).toBe(false); 14 | expect(isEmptyDeep(data3)).toBe(false); 15 | expect(isEmptyDeep(data4)).toBe(false); 16 | expect(isEmptyDeep(data5)).toBe(false); 17 | expect(isEmptyDeep(data6)).toBe(false); 18 | }); 19 | it('should return false, deep objects has primitive values', () => { 20 | const deepObject = { a: { b: 0 } }; 21 | const deepObject2 = { a: { b: 1 } }; 22 | const deepObject3 = { a: { b: '1' } }; 23 | const deepObject4 = { a: { b: true } }; 24 | const deepObject5 = { a: { b: false } }; 25 | const deepObject6 = { a: { b: undefined, c: 1 } }; 26 | 27 | expect(isEmptyDeep(deepObject)).toBe(false); 28 | expect(isEmptyDeep(deepObject2)).toBe(false); 29 | expect(isEmptyDeep(deepObject3)).toBe(false); 30 | expect(isEmptyDeep(deepObject4)).toBe(false); 31 | expect(isEmptyDeep(deepObject5)).toBe(false); 32 | expect(isEmptyDeep(deepObject6)).toBe(false); 33 | }); 34 | it('should return true, {} is empty', () => { 35 | const data = {}; 36 | 37 | expect(isEmptyDeep(data)).toBe(true); 38 | }); 39 | it('should return true, objects with null, NaN, undefined, empty string, [], {}', () => { 40 | const data = { a: null }; 41 | const data2 = { a: NaN }; 42 | const data3 = { a: undefined }; 43 | const data4 = { a: '' }; 44 | const data5 = { a: {} }; 45 | const data6 = { a: [] }; 46 | 47 | expect(isEmptyDeep(data)).toBe(true); 48 | expect(isEmptyDeep(data2)).toBe(true); 49 | expect(isEmptyDeep(data3)).toBe(true); 50 | expect(isEmptyDeep(data4)).toBe(true); 51 | expect(isEmptyDeep(data5)).toBe(true); 52 | expect(isEmptyDeep(data6)).toBe(true); 53 | }); 54 | it('should return true, objects with child object null, NaN, undefined, empty string, [], {}', () => { 55 | const data = { a: { b: null } }; 56 | const data2 = { a: { b: NaN } }; 57 | const data3 = { a: { b: undefined } }; 58 | const data4 = { a: { b: '' } }; 59 | const data5 = { a: { b: {} } }; 60 | const data6 = { a: { b: [] } }; 61 | 62 | expect(isEmptyDeep(data)).toBe(true); 63 | expect(isEmptyDeep(data2)).toBe(true); 64 | expect(isEmptyDeep(data3)).toBe(true); 65 | expect(isEmptyDeep(data4)).toBe(true); 66 | expect(isEmptyDeep(data5)).toBe(true); 67 | expect(isEmptyDeep(data6)).toBe(true); 68 | }); 69 | it('should return false, objects has arrays with primitive values ', () => { 70 | const data = { a: [0] }; 71 | const data2 = { a: [1] }; 72 | const data3 = { a: ['1'] }; 73 | const data4 = { a: [false] }; 74 | const data5 = { a: [true] }; 75 | const data6 = { a: [undefined, 1] }; 76 | const data7 = { a: [null, '1'] }; 77 | const data8 = { a: [NaN, true] }; 78 | 79 | expect(isEmptyDeep(data)).toBe(false); 80 | expect(isEmptyDeep(data2)).toBe(false); 81 | expect(isEmptyDeep(data3)).toBe(false); 82 | expect(isEmptyDeep(data4)).toBe(false); 83 | expect(isEmptyDeep(data5)).toBe(false); 84 | expect(isEmptyDeep(data6)).toBe(false); 85 | expect(isEmptyDeep(data7)).toBe(false); 86 | expect(isEmptyDeep(data8)).toBe(false); 87 | }); 88 | it('should return false, objects has deep arrays with values ', () => { 89 | const data = { a: [[0]] }; 90 | const data2 = { a: [[1]] }; 91 | const data3 = { a: [['1']] }; 92 | const data4 = { a: [[false]] }; 93 | const data5 = { a: [[true]] }; 94 | const data6 = { a: [[undefined, 1]] }; 95 | const data7 = { a: [[null, '1']] }; 96 | const data8 = { a: [[NaN, true]] }; 97 | const data9 = { a: [[0], undefined] }; 98 | const data10 = { a: [{ a: 1 }] }; 99 | const data11 = { a: [{ a: [1] }] }; 100 | 101 | expect(isEmptyDeep(data)).toBe(false); 102 | expect(isEmptyDeep(data2)).toBe(false); 103 | expect(isEmptyDeep(data3)).toBe(false); 104 | expect(isEmptyDeep(data4)).toBe(false); 105 | expect(isEmptyDeep(data5)).toBe(false); 106 | expect(isEmptyDeep(data6)).toBe(false); 107 | expect(isEmptyDeep(data7)).toBe(false); 108 | expect(isEmptyDeep(data8)).toBe(false); 109 | expect(isEmptyDeep(data9)).toBe(false); 110 | expect(isEmptyDeep(data10)).toBe(false); 111 | expect(isEmptyDeep(data11)).toBe(false); 112 | }); 113 | it('should return true, objects has arrays with NaN, null, undefined, [], {}', () => { 114 | const data = { a: [undefined] }; 115 | const data2 = { a: [''] }; 116 | const data3 = { a: [null] }; 117 | const data4 = { a: [NaN] }; 118 | const data5 = { a: [[]] }; 119 | const data6 = { a: [{}] }; 120 | const data7 = { a: [{ a: undefined }] }; 121 | const data8 = { a: [{ a: [] }] }; 122 | 123 | expect(isEmptyDeep(data)).toBe(true); 124 | expect(isEmptyDeep(data2)).toBe(true); 125 | expect(isEmptyDeep(data3)).toBe(true); 126 | expect(isEmptyDeep(data4)).toBe(true); 127 | expect(isEmptyDeep(data5)).toBe(true); 128 | expect(isEmptyDeep(data6)).toBe(true); 129 | expect(isEmptyDeep(data7)).toBe(true); 130 | expect(isEmptyDeep(data8)).toBe(true); 131 | }); 132 | it('should return true, objects has deep arrays with NaN, null, undefined, [], {}', () => { 133 | const data = { a: [[undefined]] }; 134 | const data2 = { a: [['']] }; 135 | const data3 = { a: [[null]] }; 136 | const data4 = { a: [[NaN]] }; 137 | const data5 = { a: [[[]]] }; 138 | const data6 = { a: [[{}]] }; 139 | const data7 = { a: [[{ a: null }]] }; 140 | const data8 = { a: [[{ a: [''] }]] }; 141 | 142 | expect(isEmptyDeep(data)).toBe(true); 143 | expect(isEmptyDeep(data2)).toBe(true); 144 | expect(isEmptyDeep(data3)).toBe(true); 145 | expect(isEmptyDeep(data4)).toBe(true); 146 | expect(isEmptyDeep(data5)).toBe(true); 147 | expect(isEmptyDeep(data6)).toBe(true); 148 | expect(isEmptyDeep(data7)).toBe(true); 149 | expect(isEmptyDeep(data8)).toBe(true); 150 | }); 151 | }); 152 | --------------------------------------------------------------------------------