{"id":15578153,"url":"https://github.com/el-dringo-brannde/perfected-prototypes","last_synced_at":"2025-04-24T01:10:43.929Z","repository":{"id":32816358,"uuid":"143498464","full_name":"El-Dringo-Brannde/Perfected-Prototypes","owner":"El-Dringo-Brannde","description":"An extension to the common prototype object chain to help make JS fun again","archived":false,"fork":false,"pushed_at":"2022-12-03T18:36:25.000Z","size":470,"stargazers_count":5,"open_issues_count":16,"forks_count":1,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-04-20T11:51:26.348Z","etag":null,"topics":["angular","javascript","lodash","nodejs","prototype-chain","reactjs","utility-library"],"latest_commit_sha":null,"homepage":"https://www.npmjs.com/package/perfected-prototypes","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/El-Dringo-Brannde.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":".github/CONTRIBUTING.md","funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2018-08-04T04:46:49.000Z","updated_at":"2024-05-15T08:13:00.000Z","dependencies_parsed_at":"2023-01-14T22:30:57.403Z","dependency_job_id":null,"html_url":"https://github.com/El-Dringo-Brannde/Perfected-Prototypes","commit_stats":null,"previous_names":[],"tags_count":6,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/El-Dringo-Brannde%2FPerfected-Prototypes","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/El-Dringo-Brannde%2FPerfected-Prototypes/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/El-Dringo-Brannde%2FPerfected-Prototypes/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/El-Dringo-Brannde%2FPerfected-Prototypes/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/El-Dringo-Brannde","download_url":"https://codeload.github.com/El-Dringo-Brannde/Perfected-Prototypes/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":250540941,"owners_count":21447427,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["angular","javascript","lodash","nodejs","prototype-chain","reactjs","utility-library"],"created_at":"2024-10-02T19:06:36.980Z","updated_at":"2025-04-24T01:10:43.907Z","avatar_url":"https://github.com/El-Dringo-Brannde.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"## Perfected-Prototypes\n[![npm version](https://badge.fury.io/js/perfected-prototypes.svg)](https://badge.fury.io/js/perfected-prototypes) [![Build Status](https://travis-ci.org/El-Dringo-Brannde/Perfected-Prototypes.svg?branch=master)](https://travis-ci.org/El-Dringo-Brannde/Perfected-Prototypes)\n\n\nAn extension to the Javascript Object, Array, and String prototype chain. Extending the limited functionality to what it should have been the first time around. Such as being able to search for things logically within an array, getting the first and last elements of an array. Or even being able to safely dereference an object without crashing. \n\n\n### Features \n- Small package size (~29.1kB)\n- Well tested\n- Easy to install \n- JSdoc documentated\n- Works both in ES5 \u0026 up,  and Node.JS\n- Uses `Object.defineProperty` to avoid pollution of chain methods\n- Checks to make sure there isn't overwritten methods \n\n## Installation \n\nUsing NPM: \n\n``` javascript \n$ npm install -s perfected-prototypes\n```\n\nOr Yarn: \n``` javascript \n$ yarn add perfected-prototypes\n```\n\n## Testing \n\nSimply run a `npm install` to add the testing library\nThen run: \n```bash\n$ npm run test\n```\n\n## Usage\nSimply require the module into your NodeJS project, no need to assign it to a variable or anything: \n\n``` javascript \nrequire('perfected-prototypes')\n```\n\nOr, if you want to use it on the front end say in a React or Angular Project: \n\n``` javascript \nimport \"perfected-prototypes\"\n```\n\n\nAnd that's it! You're ready to go. \n\n\n# API \n\n## Object Methods: \n\n### *Object.try()* \n\nSafely access any value on an object and have it return `false` upon not finding value, Example: \n\n``` javascript\nrequire('perfected-prototypes')\n\nconst foo = {\n   a: {\n      b: 1, \n      c: [1,2,3]\n   }\n}\n\nconsole.log(foo.try('a.b'))\n// =\u003e 1\n\nconsole.log(foo.try('a.c[1]'))\n// =\u003e 2\n\nconsole.log(foo.try('a.b.c.d.e.f'))\n// =\u003e undefined\n```\n\n\n### *Object.eachKeyValue()* \nLoop over each key and value returning undefined\n``` javascript \nconst foo = { a: 1, b: 2 }\n\nfoo.eachKeyValue((key, val) =\u003e {\n   console.log(key, val)\n})\n\n// =\u003e a 1\n// =\u003e b 2\n```\n\n### *Object.mapOver()*\nSimilar to `forEach` But this returns the objects returned at the end of the mapOver function\n``` javascript\nconst foo = { a: 1, b: 2 }\n\nconsole.log(foo.mapOver((key, val) =\u003e {\n            key = key + '1'\n            val = val * 2\n            return { [key]: val }\n         })\n)\n// =\u003e {a1: 2, b2:4}\n```\n\n\n### *Object.reduce()*\nReduce the values witin an object to summate them \n``` javascript\nconst foo = { a: 1, b: 2, c: 3, d: 4 }\n\nconsole.log(foo.reduce((prev, [key, val]) =\u003e prev + val, 0))\n// =\u003e 10\n\nconst foo = { a: 1, b: 2, c: 3, d: 4 }\n\nconsole.log(foo.reduce((prev, [key, val]) =\u003e {prev.push(val); return prev}, []))\n// =\u003e [1,2,3,4]\n```\n\n\n\n### *Object.hasData()*\nTest to see if there is any values within your object\n ```javascript\n const foo = {}\n\n console.log(foo.hasData())\n // =\u003e true\n ```\n\n OR: \n\n ```javascript\nconst foo = {a:1}\n\nconsole.log(foo.hasData())\n// =\u003e false\n ```\n\n\n### *Object.mergeObjects()*\nMerge one or any amount of objects together, with key/value presedence dependent on order of objects passed in\n``` javascript\nconst foo = {a:1}\nconst bar = {b:2}\n\nconsole.log(foo.mergeObjects(bar))\n// =\u003e {a:1, b:2}\n```\n\nOR: \n\n```javascript\nconst foo = {a:1}\nconst bar = {b:2}\nconst baz = {c:3}\n\nconsole.log(foo.mergeObjects(bar,baz))\n// =\u003e {a:1, b:2, c:3}\n```\n\n\n### *Object.deepCopy()*\nDeep copy the object with `JSON.parse(JSON.stringify())`, erasing any object references\n\n```javascript\nconst foo = {a:1, b:2}\n\nconst bar = foo.deepCopy()\nbar.a = 2\n\nconsole.log(bar)\n// =\u003e {a:2,b:2}\n\nconsole.log(foo)\n// =\u003e {a:1, b:2}\n```\n\n### *Object.deepEqual()*\nChecks the equality between two objects\n``` javascript\nconst obj1 = {a: 1, b:'2'}\nconst obj2 = {a: 1, b:'2'}\n\nconsole.log(obj1.deepEqual(obj2))\n// =\u003e true\n```\n\n\n### *Object.isObject()*\nChecks to see if the value passed in is an object (not arrays or functions)\n**Also on the actual Object not on the prototype chain**\n``` javascript\nconst foo = {}\nconst bar = []\nconst baz = function() { return 2}\n\nconsole.log(Object.isObject(foo))\n// =\u003e true\n\nconsole.log(Object.isObject(bar))\n// =\u003e false\n\nconsole.log(Object.isObject(baz))\n// =\u003e false\n\n```\n\n\n## Array Methods: \n### *Array.first*\nA getter to easily get the *first* element of an array\n``` javascript\nconst arr = [1,2,3,4,5]\n\nconsole.log(arr.first)\n// =\u003e 1\n```\n\n### *Array.last* \nA getter to easily get the *last* element of the array\n``` javascript\nconst arr = [1,2,3,4,5]\n\nconsole.log(arr.last)\n// =\u003e 5\n```\n\n### *Array.access()*\nAccess values within the array in a python like style, such that negative indexing is allowed\n\n``` javascript\nconst arr = [1,2,3]\n\nconsole.log(arr.access(-1))\n// =\u003e 3\n```\n\n### *Array.remove()*\nRemove all instances of a value within the array and return new array\n\n```javascript\nconst arr = [1,2,2,3,4,5]\n\nconsole.log(arr.remove(2))\n// =\u003e [1,3,4,5]\n```\n\n### *Array.yank()* \nReturns and removes the specified values and mutates the actual array\n``` javascript\nconst arr = [1,2,3,4,5]\n\nconsole.log(arr.yank(2))\n// =\u003e 2\nconsole.log(arr)\n// =\u003e [1,3,4,5]\n\nconsole.log(arr.yank([3,4]))\n// =\u003e [3,4]\nconsole.log(arr)\n// =\u003e [1,2,5]\n```\n\n### *Array.clear()* \nClear the array being worked on, and return a new empty array\n``` javascript \nconst arr = [1,2,3,4,5]\n\nconsole.log(arr.clear())\n// =\u003e []\n```\n\nOR: \n```javascript\n\nconst arr = [1,2,3,4,5]\narr.clear()\n\nconsole.log(arr)\n// =\u003e []\n```\n\n### *Array.unique()*\nGet the unique values of an array\n``` javascript\nconst arr = [1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 5, 5, 5, 6]\n\nconsole.log(arr.unique())\n// =\u003e [1,2,3,4,5,6]\n```\n\n### *Array.uniqueBy()*\nFilter an array of objects to unique set of objects by some selector\n\n``` javascript\nconst arr = [{ name: 'bob', job: 'wood' }, { name: 'bob', job: 'wood' }]\n\nconsole.log(arr.uniqueBy('name'))\n// =\u003e [{ name: 'bob', job: 'wood' }]\n\n```\n\n### *Array.isEmpty()*\nChecks to see if the array is empty \n\n```javascript\nconst arr = [1,2,3]\nconsole.log(arr.isEmpty())\n// =\u003e false\n\nconst arr  = []\nconsole.log(arr.isEmpty())\n// =\u003e true\n```\n\n### *Array.findObj()*\nSearch for the first value that matches query in array, implemented with lodash 'find' function\n\nUsing a function:\n``` javascript\nconst users = [\n   { 'user': 'barney', 'age': 36, 'active': true },\n   { 'user': 'fred', 'age': 40, 'active': false },\n   { 'user': 'pebbles', 'age': 1, 'active': true }\n];\n\n\nconsole.log(users.findObj(o =\u003e { return o.age \u003c 40 }))\n// =\u003e { 'user': 'barney', 'age': 36, 'active': true }\n```\n\nUsing an object:\n```javascript\n\nconst users = [\n   { 'user': 'barney', 'age': 36, 'active': true },\n   { 'user': 'fred', 'age': 40, 'active': false },\n   { 'user': 'pebbles', 'age': 1, 'active': true }\n];\n\nconsole.log(const res = users.findObj({ 'user': 'barney', 'age': 36, 'active': true }))\n// =\u003e { 'user': 'barney', 'age': 36, 'active': true }\n```\n\nUsing array of values: \n``` javascript\nconst users = [\n   { 'user': 'barney', 'age': 36, 'active': true },\n   { 'user': 'fred', 'age': 40, 'active': false },\n   { 'user': 'pebbles', 'age': 1, 'active': true }\n];\n\nconsole.log(users.findObj(['active', false]))\n// =\u003e { 'user': 'fred', 'age': 40, 'active': false }\n```\n\n\nUsing a single level value: \n\n```javascript\nconst users = [\n   { 'user': 'barney', 'age': 36, 'active': true },\n   { 'user': 'fred', 'age': 40, 'active': false },\n   { 'user': 'pebbles', 'age': 1, 'active': true }\n];\n\nconsole.log(users.findObj('active'))\n// =\u003e { 'user': 'barney', 'age': 36, 'active': true }\n\n```\n### *Array.diff()*\nFind the difference between two arrays, empty if no difference\n\n``` javascript\nconst arr1 = [1,2,3]\nconst arr2 = [1]\n\nconsole.log(arr1.diff(arr2))\n// =\u003e [2,3]\n```\n\n### *Array.shuffle()*\nUsing the current array, shuffle the values and return new array (Doesn't mutate original). \n\n```javascript\n   const arr = [1,2,3,4]\n   console.log(arr.shuffle())\n   // =\u003e [2,3,1,4]\n```\n\n### *Array.deepEqual()*\nCheck the equality between two arrays returning a boolean\n\n``` javascript\n   const arr1 = [1,2,false, 'boo']\n   const arr2 = [1,2,false, 'boo']\n   \n   console.log(arr1.deepEqual(arr2))\n   // =\u003e true\n```\n\n## String Methods\n\n### *String.camelCase()*\nTurn a string into camel case: I.E - 'Brandon Dring' -\u003e 'brandonDring'\n\n``` javascript \nconst str =  'Brandon Dring'\n\nconsole.log(str.camelCase())\n// =\u003e 'brandonDring'\n```\n\n### *String.numberize()*\nAdd appropriate commas to a whole number (No decimals)\n```javascript\nconst str = '1000000'\nconsole.log(str.numberize())\n// =\u003e '1,000,000'\n```\n\n### *String.HTMLescape()*\nEscape a string ready for HTML insertion: Jekyll \u0026 Hyde -\u003e Jekyll \u0026amp; Hyde\n\n```javascript\n   const str = 'Jekyll \u0026 Hyde'\n\n   console.log(str.HTMLescape())\n   // =\u003e 'Jekyll \u0026amp; Hyde'\n```\n\n### *String.startCase()*\nCapitalize the first letter in every word of the string (good for names)\n```javascript\nconst str = 'brandon dring'\nconsole.log(str.startCase())\n// =\u003e 'Brandon Dring'\n```\n\n### *String.contains()*\nCheck to see if a given value is within a string\n```javascript \nconst str = 'The quick brown fox jumps over the lazy dog'\n\nconsole.log(str.contains('fox'))\n// =\u003e true\n```\n\n### *String.isString()*\nCheck to see if the value is a string (On the actual `String` object)\n``` javascript \nconst str = 'Hello world!'\n\nconsole.log(String.isString(str))\n// =\u003e true\n```\n\n\n## Number Methods\n\n### *Number.round()*\nRound a number to a decimal place\n``` javascript \n\nconst num = 1.23456\n\nconsole.log(num.round())\n\n// =\u003e 1\n\nconsole.log(num.round(2))\n// =\u003e 1.23\n```\n\n### *Number.random()*\nGenerate a random number between the two parameters\n```javascript\n\nconsole.log(Number.random(0,5))\n// =\u003e Between 0-5\n```\n\n\n### *Number.isNumber()*\nCheck to see if the value is a number or not (On the `Number` object not prototype chain)\n\n```javascript \nconst num = 12345\n\n\nconsole.log(Number.isNumber(num))\n// =\u003e true\n```\n\n\n\n## Contributing\nPlease feel free to add an issue, or create a pull request to add extra functionality to the prototype chain. However, I don't want to pollute the chain with the entire library of lodash persay, just the most useful functions.\n\n\n\n#### Ackowledgements\n\nCDK Global's annual hackathon for giving me the time to work on this.\n\n[prototypes](https://www.npmjs.com/package/prototypes) for the general idea. \n\n[Lodash](https://github.com/lodash/lodash) for their library to solve common issues\n\n\n\n\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fel-dringo-brannde%2Fperfected-prototypes","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fel-dringo-brannde%2Fperfected-prototypes","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fel-dringo-brannde%2Fperfected-prototypes/lists"}