├── .gitignore ├── LICENSE ├── arrayMethods.js ├── arrayMethods.test.js ├── package-lock.json └── package.json /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 WebDevSimplified 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /arrayMethods.js: -------------------------------------------------------------------------------- 1 | function forEach(array, cb) { 2 | for (let i = 0; i < array.length; i++) { 3 | cb(array[i], i, array) 4 | } 5 | } 6 | 7 | function map(array, cb) { 8 | const newArray = [] 9 | for (let i = 0; i < array.length; i++) { 10 | newArray.push(cb(array[i], i, array)) 11 | } 12 | 13 | return newArray 14 | } 15 | 16 | function filter(array, cb) { 17 | const newArray = [] 18 | for (let i = 0; i < array.length; i++) { 19 | const element = array[i] 20 | if (cb(element, i, array)) newArray.push(element) 21 | } 22 | 23 | return newArray 24 | } 25 | 26 | function reduce(array, cb, initialValue) { 27 | let currentValue = initialValue 28 | for (let i = 0; i < array.length; i++) { 29 | const element = array[i] 30 | if (initialValue == null && i === 0) { 31 | currentValue = element 32 | } else { 33 | currentValue = cb(currentValue, element, i, array) 34 | } 35 | } 36 | 37 | return currentValue 38 | } 39 | 40 | function some(array, cb) { 41 | for (let i = 0; i < array.length; i++) { 42 | if (cb(array[i], i, array)) return true 43 | } 44 | 45 | return false 46 | } 47 | 48 | function every(array, cb) { 49 | for (let i = 0; i < array.length; i++) { 50 | if (!cb(array[i], i, array)) return false 51 | } 52 | 53 | return true 54 | } 55 | 56 | function flat(array, depth = 1) { 57 | const newArray = [] 58 | for (let i = 0; i < array.length; i++) { 59 | const element = array[i] 60 | if (Array.isArray(element) && depth > 0) { 61 | newArray.push(...flat(element, depth - 1)) 62 | } else { 63 | newArray.push(element) 64 | } 65 | } 66 | return newArray 67 | } 68 | 69 | function find(array, cb) { 70 | for (let i = 0; i < array.length; i++) { 71 | const element = array[i] 72 | if (cb(element, i, array)) return element 73 | } 74 | } 75 | 76 | module.exports = { 77 | forEach, 78 | map, 79 | filter, 80 | reduce, 81 | some, 82 | every, 83 | flat, 84 | find, 85 | } 86 | -------------------------------------------------------------------------------- /arrayMethods.test.js: -------------------------------------------------------------------------------- 1 | const { 2 | forEach, 3 | map, 4 | filter, 5 | reduce, 6 | some, 7 | every, 8 | flat, 9 | find, 10 | } = require("./arrayMethods.js") 11 | 12 | // const forEach = (a, ...args) => a.forEach(...args) 13 | // const map = (a, ...args) => a.map(...args) 14 | // const filter = (a, ...args) => a.filter(...args) 15 | // const reduce = (a, ...args) => a.reduce(...args) 16 | // const some = (a, ...args) => a.some(...args) 17 | // const every = (a, ...args) => a.every(...args) 18 | // const flat = (a, ...args) => a.flat(...args) 19 | // const find = (a, ...args) => a.find(...args) 20 | 21 | it("forEach", () => { 22 | const func = jest.fn() 23 | const startingArray = ["a", "b", "c"] 24 | forEach(startingArray, func) 25 | 26 | expect(func).toHaveBeenNthCalledWith(1, "a", 0, startingArray) 27 | expect(func).toHaveBeenNthCalledWith(2, "b", 1, startingArray) 28 | expect(func).toHaveBeenNthCalledWith(3, "c", 2, startingArray) 29 | expect(func).toHaveBeenCalledTimes(3) 30 | }) 31 | 32 | it("map", () => { 33 | const func = jest.fn((elem, index) => index * 2) 34 | const startingArray = ["a", "b", "c"] 35 | const newArray = map(startingArray, func) 36 | 37 | expect(newArray).toEqual([0, 2, 4]) 38 | expect(func).toHaveBeenNthCalledWith(1, "a", 0, startingArray) 39 | expect(func).toHaveBeenNthCalledWith(2, "b", 1, startingArray) 40 | expect(func).toHaveBeenNthCalledWith(3, "c", 2, startingArray) 41 | expect(func).toHaveBeenCalledTimes(3) 42 | }) 43 | 44 | it("filter", () => { 45 | const func = jest.fn((elem, index) => elem === "a" || index === 2) 46 | const startingArray = ["a", "b", "c"] 47 | const newArray = filter(startingArray, func) 48 | 49 | expect(newArray).toEqual(["a", "c"]) 50 | expect(func).toHaveBeenNthCalledWith(1, "a", 0, startingArray) 51 | expect(func).toHaveBeenNthCalledWith(2, "b", 1, startingArray) 52 | expect(func).toHaveBeenNthCalledWith(3, "c", 2, startingArray) 53 | expect(func).toHaveBeenCalledTimes(3) 54 | }) 55 | 56 | describe("reduce", () => { 57 | it("with a starting value", () => { 58 | const func = jest.fn((sum, elem) => sum + elem) 59 | const startingArray = [5, 3, 7] 60 | const total = reduce(startingArray, func, 4) 61 | 62 | expect(total).toEqual(19) 63 | expect(func).toHaveBeenNthCalledWith(1, 4, 5, 0, startingArray) 64 | expect(func).toHaveBeenNthCalledWith(2, 9, 3, 1, startingArray) 65 | expect(func).toHaveBeenNthCalledWith(3, 12, 7, 2, startingArray) 66 | expect(func).toHaveBeenCalledTimes(3) 67 | }) 68 | 69 | it("with no starting value", () => { 70 | const func = jest.fn((sum, elem) => sum + elem) 71 | const startingArray = [5, 3, 7] 72 | const total = reduce(startingArray, func) 73 | 74 | expect(total).toEqual(15) 75 | expect(func).toHaveBeenNthCalledWith(1, 5, 3, 1, startingArray) 76 | expect(func).toHaveBeenNthCalledWith(2, 8, 7, 2, startingArray) 77 | expect(func).toHaveBeenCalledTimes(2) 78 | }) 79 | }) 80 | 81 | describe("some", () => { 82 | it("with a truthy value", () => { 83 | const func = jest.fn(elem => elem > 0) 84 | const startingArray = [-4, 3, 6] 85 | const result = some(startingArray, func) 86 | 87 | expect(result).toEqual(true) 88 | expect(func).toHaveBeenNthCalledWith(1, -4, 0, startingArray) 89 | expect(func).toHaveBeenNthCalledWith(2, 3, 1, startingArray) 90 | expect(func).toHaveBeenCalledTimes(2) 91 | }) 92 | 93 | it("with no truthy values", () => { 94 | const func = jest.fn(elem => elem > 0) 95 | const startingArray = [-4, -3, -6] 96 | const result = some(startingArray, func) 97 | 98 | expect(result).toEqual(false) 99 | expect(func).toHaveBeenNthCalledWith(1, -4, 0, startingArray) 100 | expect(func).toHaveBeenNthCalledWith(2, -3, 1, startingArray) 101 | expect(func).toHaveBeenNthCalledWith(3, -6, 2, startingArray) 102 | expect(func).toHaveBeenCalledTimes(3) 103 | }) 104 | }) 105 | 106 | describe("every", () => { 107 | it("with a falsey value", () => { 108 | const func = jest.fn(elem => elem < 0) 109 | const startingArray = [-4, 3, 6] 110 | const result = every(startingArray, func) 111 | 112 | expect(result).toEqual(false) 113 | expect(func).toHaveBeenNthCalledWith(1, -4, 0, startingArray) 114 | expect(func).toHaveBeenNthCalledWith(2, 3, 1, startingArray) 115 | expect(func).toHaveBeenCalledTimes(2) 116 | }) 117 | 118 | it("with no falsey values", () => { 119 | const func = jest.fn(elem => elem < 0) 120 | const startingArray = [-4, -3, -6] 121 | const result = every(startingArray, func) 122 | 123 | expect(result).toEqual(true) 124 | expect(func).toHaveBeenNthCalledWith(1, -4, 0, startingArray) 125 | expect(func).toHaveBeenNthCalledWith(2, -3, 1, startingArray) 126 | expect(func).toHaveBeenNthCalledWith(3, -6, 2, startingArray) 127 | expect(func).toHaveBeenCalledTimes(3) 128 | }) 129 | }) 130 | 131 | describe("flat", () => { 132 | it("with no value passed", () => { 133 | const startingArray = [1, [2, 3], [4, [5, 6, [7, 8]]]] 134 | const result = flat(startingArray) 135 | 136 | expect(result).toEqual([1, 2, 3, 4, [5, 6, [7, 8]]]) 137 | }) 138 | 139 | it("with a value passed", () => { 140 | const startingArray = [1, [2, 3], [4, [5, 6, [7, 8]]]] 141 | const result = flat(startingArray, 2) 142 | 143 | expect(result).toEqual([1, 2, 3, 4, 5, 6, [7, 8]]) 144 | }) 145 | 146 | it("with infinite passed", () => { 147 | const startingArray = [1, [2, 3], [4, [5, 6, [7, 8]]]] 148 | const result = flat(startingArray, Number.POSITIVE_INFINITY) 149 | 150 | expect(result).toEqual([1, 2, 3, 4, 5, 6, 7, 8]) 151 | }) 152 | }) 153 | 154 | describe("find", () => { 155 | it("with no value found", () => { 156 | const func = jest.fn(elem => elem === 5) 157 | const startingArray = [1, 2, 3] 158 | const result = find(startingArray, func) 159 | 160 | expect(result).toBeUndefined() 161 | expect(func).toHaveBeenNthCalledWith(1, 1, 0, startingArray) 162 | expect(func).toHaveBeenNthCalledWith(2, 2, 1, startingArray) 163 | expect(func).toHaveBeenNthCalledWith(3, 3, 2, startingArray) 164 | expect(func).toHaveBeenCalledTimes(3) 165 | }) 166 | 167 | it("with a value found", () => { 168 | const func = jest.fn(elem => elem === 2) 169 | const startingArray = [1, 2, 3] 170 | const result = find(startingArray, func) 171 | 172 | expect(result).toEqual(2) 173 | expect(func).toHaveBeenNthCalledWith(1, 1, 0, startingArray) 174 | expect(func).toHaveBeenNthCalledWith(2, 2, 1, startingArray) 175 | expect(func).toHaveBeenCalledTimes(2) 176 | }) 177 | }) 178 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "array-methods-clone", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "jest --watchAll --noStackTrace" 8 | }, 9 | "keywords": [], 10 | "author": "", 11 | "license": "ISC", 12 | "devDependencies": { 13 | "jest": "^27.5.1" 14 | } 15 | } 16 | --------------------------------------------------------------------------------