Monthly Archives: October 2020
JavaScript || How To Get A Variable Name As A String Using Vanilla JavaScript
The following is a module with functions which demonstrates how to get the name of a variable as a string using vanilla JavaScript.
1. Simple Variable
The example below demonstrates the use of ‘Utils.nameOf‘ to get name of a simple variable.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
// Simple Variable <script> (() => { // Get the name of the variable let simpleString = 'My Programming Notes'; console.log( Utils.nameOf({ simpleString }) ); })(); </script> // expected output: /* simpleString */ |
2. Array
The example below demonstrates the use of ‘Utils.nameOf‘ to get the name of an array.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
// Array <script> (() => { // Mixed array let mixedArray = [ [0, 'Aluminium', 0, 'Francis'], [1, 'Argon', 1, 'Ada'], [2, 'Brom', 2, 'John'], [3, 'Cadmium', 9, 'Marie'], [4, 'Fluor', 12, 'Marie'], [5, 'Gold', 1, 'Ada'], [6, 'Kupfer', 4, 'Ines'], [7, 'Krypton', 4, 'Joe'], [8, 'Sauerstoff', 0, 'Marie'], [9, 'Zink', 5, 'Max'] ]; console.log( Utils.nameOf({ mixedArray }) ); })(); </script> // expected output: /* mixedArray */ |
3. Function
The example below demonstrates the use of ‘Utils.nameOf‘ to get the name of a function.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
// Function <script> (() => { // Function function multiplyFunction(x, y) { return x * y; } console.log( Utils.nameOf({ multiplyFunction }) ); })(); </script> // expected output: /* multiplyFunction */ |
4. Utils Namespace
The following is the Utils.js Namespace. Include this in your project to start using!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
// ============================================================================ // Author: Kenneth Perkins // Date: Oct 31, 2020 // Taken From: http://programmingnotes.org/ // File: Utils.js // Description: Javascript that handles general utility functions // ============================================================================ /** * NAMESPACE: Utils * USE: Handles general utility functions. */ var Utils = Utils || {}; (function(namespace) { 'use strict'; // Property to hold public variables and functions let exposed = namespace; /** * FUNCTION: nameOf * USE: Returns the name of a variable. * @param expression: An object containing the variable to get the name of. * @return: The name of a variable. */ exposed.nameOf = (expression) => { if (expression !== Object(expression) || typeof expression === 'function' || Array.isArray(expression)) { throw new Error(`Unable to determine name. '${expression}' is not an object`); } return Object.keys(expression)[0]; } (function (factory) { if (typeof define === 'function' && define.amd) { define([], factory); } else if (typeof exports === 'object') { module.exports = factory(); } }(function() { return namespace; })); }(Utils)); // http://programmingnotes.org/ |
QUICK NOTES:
The highlighted lines are sections of interest to look out for.
The code is heavily commented, so no further insight is necessary. If you have any questions, feel free to leave a comment below.
JavaScript/CSS/HTML || Notice.js – Simple Notification Message With Success, Warning & Error Icons Using Vanilla JavaScript
The following is a module with functions that demonstrates how to display a simple notification message with success, warning & error icons.
Using vanilla JavaScript, the message fades in and is displayed to the page, and fades out after a delay (in milliseconds). It’s look and feel can also be adjusted via CSS.
Contents
1. Basic Usage
2. Notice HTML
3. Notice.js & CSS Source
4. More Examples
1. Basic Usage
Syntax is very straightforward. The following demonstrates the JavaScript used to show the notification message. The message fades away after a specified amount of time (in milliseconds).
1 2 3 4 5 6 7 8 9 10 |
<!-- Display Message. --> <div class="notice hide"></div> <script> document.addEventListener("DOMContentLoaded", function(eventLoaded) { // Display Message Notice.display(document.querySelector('.notice'), 'Success', Notice.type.success, 3000); }); </script> |
2. Notice HTML
If you wish to show the messages without using JavaScript, the following is an example of the HTML used to display the notices.
1 2 3 |
<!-- // HTML - Success --> <div class="notice"> Success </div> |
1 2 3 |
<!-- // HTML - Warning --> <div class="notice warning"> Warning </div> |
1 2 3 |
<!-- // HTML - Error --> <div class="notice error"> Error </div> |
3. Notice.js & CSS Source
The following is the Notice.js Namespace & CSS Source. Include this in your project to start using!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 |
// ============================================================================ // Author: Kenneth Perkins // Date: Oct 31, 2020 // Taken From: http://programmingnotes.org/ // File: Notice.js // Description: Javascript that displays a Notice to the screen // ============================================================================ /** * NAMESPACE: Notice * USE: Displays a Notice to the screen. */ var Notice = Notice || {}; (function(namespace) { 'use strict'; // -- Public data -- // Property to hold public variables and functions let exposed = namespace; // Set class names and other shared data const settings = { classNameNotice: '.notice', classNameSuccess: '', classNameWarning: '.warning', classNameError: '.error', classNameShow: '.show', classNameHide: '.hide', cleanClassName: function(str) { return str ? str.trim().replace('.', '') : ''; }, }; exposed.settings = settings; // Notice type enum const NoticeType = Object.freeze({success:1, warning:2, error:3}); exposed.type = NoticeType; /** * FUNCTION: display * USE: Displays a message to the page with the given text. * @param text: Text to be displayed to the page. * @param type: The message type. The type determines the style of the notice. * @param duration: The length the notice is displayed to the page (in milliseconds). * Set value to null to display the notice indefinitely. * @return: N/A. */ exposed.display = (element, text, type = Notice.type.success, duration = 3000) => { // Make sure the notice element exists if (!element) { throw new Error('Notice element does not exist'); } let id = getId(element); // Remove any previously existing notice duration delay if (noticeClearTimeout[id]) { clearTimeout(noticeClearTimeout[id]); } // Style the notice depending on the notice type applyStyleType(element, type); // Set the notice text element.innerHTML = text; // Fade in the notice to make it visible fadeIn(element); // Set the notice display duration if (duration) { noticeClearTimeout[id] = setTimeout(() => { // Fade out the notice to make it invisible fadeOut(element); delete noticeClearTimeout[id]; }, duration); } } // -- Private data -- // Holds the notice duration timeout delay let noticeClearTimeout = {}; let applyStyleType = (element, type) => { // Define the css classes for the different notice types let styles = getStyles(); // Remove previous styles for the notice and set the new one for (const style of styles) { if (style.class.length < 1) { continue; } // Check if the class is applied let classExists = hasClass(element, style.class); // Add the selected class if (type && type === style.type) { if (!classExists) { addClass(element, style.class); } } else if (classExists) { // Remove class if exists removeClass(element, style.class); } } } let getId = (element) => { if (!element.id || element.id.trim().length < 1) { element.id = `notice_${randomFromTo(1271991, 7281987)}`; } return element.id; } let randomFromTo = (from, to) => { return Math.floor(Math.random() * (to - from + 1) + from); } let getStyles = () => { let styles = [ {type: NoticeType.success, class: settings.classNameSuccess}, {type: NoticeType.warning, class: settings.classNameWarning}, {type: NoticeType.error, class: settings.classNameError} ]; return styles; } let fadeIn = (element) => { removeClass(element, settings.classNameHide); addClass(element, settings.classNameShow); } let fadeOut = (element) => { removeClass(element, settings.classNameShow); addClass(element, settings.classNameHide); } let addClass = (element, cssClass) => { cssClass = settings.cleanClassName(cssClass); let modified = false; if (cssClass.length > 0 && !hasClass(element, cssClass)) { element.classList.add(cssClass) modified = true; } return modified; } let removeClass = (element, cssClass) => { cssClass = settings.cleanClassName(cssClass); let modified = false; if (cssClass.length > 0 && hasClass(element, cssClass)) { element.classList.remove(cssClass); modified = true; } return modified; } let hasClass = (element, cssClass) => { cssClass = settings.cleanClassName(cssClass); return element.classList.contains(cssClass); } (function (factory) { if (typeof define === 'function' && define.amd) { define([], factory); } else if (typeof exports === 'object') { module.exports = factory(); } }(function() { return namespace; })); }(Notice)); // http://programmingnotes.org/ |
The following is Notice.css.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 |
/* // ============================================================================ // Author: Kenneth Perkins // Date: Oct 31, 2020 // Taken From: http://programmingnotes.org/ // File: Notice.css // Description: CSS for the notifiaction display // ============================================================================ */ .notice { border: 1px solid #d6dadb; border-left: 4.5px solid #32b032; background-color: #f1f5f6; text-align:left; padding: 8px; font-family: helvetica,arial,sans-serif; transition: opacity 400ms ease-in-out; } /* Background url source: http://icons.iconarchive.com/icons/custom-icon-design/flatastic-9/256/Accept-icon.png */ .notice:before { width: 18px; height: 18px; margin-right: 10px; content: ""; display: inline-block; vertical-align: middle; background-image: url('data:image/png;base64,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'); background-size: 100%; background-repeat: no-repeat; transform: translateY(-10%); } .notice.error { border-left-color: red; } /* Background url source: http://icons.iconarchive.com/icons/papirus-team/papirus-status/256/dialog-error-icon.png */ .notice.error:before { background-image: url('data:image/png;base64,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'); } .notice.warning { border-left-color: #ff8000; } /* Background url source: http://icons.iconarchive.com/icons/papirus-team/papirus-status/256/dialog-warning-icon.png */ .notice.warning:before { background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAQAAAAEACAYAAABccqhmAAAACXBIWXMAAA7EAAAOxAGVKw4bAAAgAElEQVR42u2dd3gc1fX+3zszu6u2qrYl25LcJFc6pkOAUEIzCQn8HEgCDiV0YQMJxRAIEBsnccEYSCgxzQZCMNi0L6bZhO6Ouyw3SbaK1Xe1bcr9/bErLMndWpXZfT/PMw/e0bK7c+857z3nzL13AEIIIYQQQgghhBBCCCGEEEIIIYQQQgghhBBCCCGEEEIIIYQQQgghhBBCCCGEEEIIIYQQQkiXItgEsYXccFcqNOQD6AWJLAiRASATEumAlQQhnLCkC6pIhIQz8n+FYMEPRQQhZQhQfBBoAFAHKeshUAuJGqhqqRj8tya2MgWAdKeTlxSlA45jADEKEgMhZAEg8gDkQYjenduvshFSlgIoh7Q2QagbIeU6CH2lKJjZwN6hAJBoutumu9IhcDpUnAgLR0PiaAglD4DS034qpKwCsBoCK2DJJbDwhRg2tZq9SAEgBz2635kPKOcB1imAcjIgRkD0OGc/FFHYAuBrAIsg5SeicGope5kCQH50+LudgDwNEhdA4AJAORIiZvtFQlqbAPEhpPwIAp+JgqlBWgEFIN7C+gQIcRGk/DUUcSEgUjrvy6zwAROABKSM/MFq98ZIkCFExCxUQCjho/PwwrI+AOQ7gJgvCqf6aB0UgFgd6R2QcgwgLocQl0DA3fEPNQHLAKQOSKPtATPi+LLjJiKUiCBo7Q4HoGiAUKPQQNIPab0PiLkA3hOFU3VaDQUgBhz/ruGQuBqKMg5A38N0jrCTW0HA0gEZihxGD7lKFVCcgHCG/6u4wuIgDtO8JGoA60XAelEUTF9LK6IA2Mzp73QAYiyEuB5S/OSQc3ppAVYg4vDB8L/3CNltYFqKC1ASdh+Hnk5ISOt7SMyCkG+IgmmMCigAPTq3TwXwBwgxHkL0P7QRPgSYfsCKHLGI4gKUJEBJjEQJh2B+UlZDyieg4F9iyNRaWhsFoOc4/oa7BkETRQCugxDug3Z6yweYzYDps+EI32E1ANQkQE0Oi8LBioGUzYCcDUWdKgb/bRutjwLQjSP+3bkQ8n4I5TqgZVotnf7w0oVkQDsUMZA6hPIyLP9jouBJCgEFoCtz/LtyAHEvhLgRQMIB/wcrBBgewPTQ6Q8qMkgBNHc4TThwlSAIWP+GxGRROLWM7UcB6MwRPxmQ90OICRAicf9vtsIOb3jC+T05DOt0hoVAdR+4gCilH5DTATlZFEzzsvEoAFEc8e8WkPK3EGIShMjd/2hvAGZj2PE52kfPTFU3oKUBiuNAvVUJ03oAivi3KJgq2XYUgA6O+nedAkXMAMSJ+3f8AKA3AlYzG61TM4QkwJEevq243/6wlkHI20TBtG/ZaBSAwxj173QD4jEI5VYA6v4dvz52b931WCFIALQMQN1vJmZBWs8C8h5RMI37GFAADtL5t/7pYpjW0xAin45vByHIBNSE/dUHyqGIW8Xgvy9gg1EA9hfuZwJ4Eopy5T7bxgoBei0dv0emBpnhqcj76F5I87+Q4iZROLWODUYBaO/8P4VQXoRA3t7fYIZHfJORZI9GdYeFYF8LlKSsgJS/FYVTP2NjUQAgi+90QlEehRB37TXXlxIwGgGjAazq28istYzwXYO9TyqyIK0nIK37ROH0IAUgXp2/5M5BgDIPQhyz1zeYAUCv4X1821q3E3D02nd9QMoVkNZYUThtEwUg7px/whgI9RVApO35RwvQ6xjux0xakBpJC5S9iUADpHGNKJyxgAIQF45fpEA6HoKiPIC9baxp+oDQLoR30CGxY+kq4OgdXoC0h1HAAszJAB4UBdMkBSBWnX/TnekQylwIcSFHfUYDe9qA+REkxorCaY0UgNjL9/MB5QMIMWqPP1qB8Kgvud9EfFi9Bjj77H02obTWQ8oxonDaZgpAzIz8E0ZDqO9CiJx2oV+4um/wtnBcomUCWvqeXiBlFQQuFUP+8T0FwPYj/4RLIdS5gEjeI+QPVYfX55P4RUkKRwPtUwIpfYC8UhRMXUABsG/OfzUU9QUAWtuQPxh2fob85MeUIHtv+w8YsIw/iMLpsykA9sv5b4ZQZ6F9pd/wAvoudHy7bBJzruDoFd5/oG2aaEEad4jC6bMoAPZx/j9CqFPaXJ8EYNSHD0L2WRdID9cGRHsZMCeKwmmTKQA93vnv+jOE8nBb55eAXh3ei4+QA9YFkiN1AdFeBB4RhdMepgD0XOf/I4TSbuQ3gVBlOO8n5KBFwAU4c9ovKpKwjPtF4fTHKQA9M+d/qq3zG0CwgsU+cpje4QBcfcNFwtYiYJpFYui0WRSAnuL8myaMg9BeaPMYbUsHQhU96PFZxJ4eogHOvu33IrRgmdeLwmmzKQDd7fxbx18KU5sH0SpWs0LhkZ/z+UlUUMORQNvNRgzAvFwMmTafAtBtI//44yG0LyBEUlvn3wmu3SdRLgoArn5tRUDKZkjjLFE4YykFoOvD/oEQ6jdtpvdy5AcAlJQbqGuKrgBmpiooyNUoAnuKQBWkcZIonLGdAtB1I38ahPZVm4U9lh4Z+Rn2P/x8ExatiO4mJmcd68TD16cyENhbOiDlWkj9dFH4RIPdrkazn/NPEID62h7OH6Lzk67ADBeXnf12FwaFGAVFnSs3jb9YFM6QFIBOjVnEI23W87fc55d0ftJVo1DE5lz9ds8TkOqFEHgEwIMUgE4b/e+8BEK9f/cJK+L8vM9PutoY9bDtOfu2Wkmo3i833blEFE5bQAGIft5fCEV5BS2Le6SMLOflDD/STbSsKnVmh6cNCygQysty0/jRonBGCQUgWs6/cbwTQvsPINJ/PKnXci3/PggZli0+MzZEwBe2RWevlhw1DUJ7QxYXnSKGzgxRAKKBqkxqs3W34eHefaTnYDYBhhPQIndJhDgOQn0MwJ8oAB0O/Sf8FEKdsLuxA5H1/IT0IPSa8HMIWp5BoGh3yuIJ/yeGTv+MAnC4zl9yRwagvrw77zeAUBWNjfRQEagClP4ti4dUKOpLsrjoGDF0Zi0F4LAUQH0Giugf/reMOD9v95Geaq9mpCjYN1IUFLmA40kAV1EADnn0v/1iCPX/7c7761nxJz0fKxC2VUdm+LWq/Fpu/eMcMejv71MADjrvv8MNOP6JlqnKpj/ycE5CbIDRACiJgJoIAAKmfEaWFI0SBTM9FICDQn08HD61CqsIsVU9oBpQcsMzBYXIg6VNAnA7BeCAo//4U6CoN/54gs/pI7atB+wCXJHFqopysyweP0cMnfEtBWCfzl8kILSZAMITrA0PJ/sQG9cDfGEb1twAhApFmymLbz9JDH1SUgD2/nOugRCjw2pghGdYEWLrVKA2/ETicCpwAhT1agAvUQDaj/7FRSkQyqTdDVcD7upDYiAMCE9cc7bsW6NNksW3vyWGPumlALRG0e6HEH3Dob8XMBn6kxjB9AGmF1BTACH6QdHuBfAABWD36N8fUMaHX1gM/UlspgJKUnjpsFAnyOLbnhJDZ1VQAABAUe+FEInh0b8erPqTmEOakQlCWQBEEoTjPgBFcS8AsrgoH9BuCKdLIcBopLGQ2MRoBFR3eD9BRbtBFt/2NzF0Vnl8RwBCnQgB149hEiGxngq4+gJAAoRjIoCb41YA5OY7BwHqOADhQonlp4GQ2Mbyh21dTQKEdq1cf8sUMeLpbfEZAVhyPBQ4w0/vraNxkDiJAuoiBUE4oTknALgj7gRAbro9A0K9Njz6NwMyRMMg8YEMhW8LaimA0H4vN976kBj2VENcCQCg3QghUiAlYHD0J3GGUQeoyYAQbijOGwFMiRsBkMW3OyDU8Moo08Mn+JI4jAKMsO1rqYBQi2TxrdPE0Kf0uBAACDEWQvQLj/5c50/iNQpoCN8WFKIfoIwF8GqcCIDjxt25P0d/Es9RQHO4FqA4b4gLAZDFtw0HlNMgwdGfEKMhvEYAyhmy+NZhYuhTG2M7AhDadRAQMH2s/BMiQ+F9A9QkAUW7FsA9MSsAsvhWB4R2TVj5OOWXkB99QU0C4BgnN97ygBj2tB6TAgAoYyBEb1ghzvojpAXLH14Hozj7QIiLAbwTmwIgnFeEFY+P9SKkbRTgAZxZgJp4RUwKgNx4awIUcQmkFZ4FRQjZjekBZAYAMUZuvClRDPunP6YEAEKMAUQKTA+41Rche+QBkVuCbjegXgTgrRgTANcVP4Y6hJC9RwGaG1BdV8SUAMgNNzuhKBfC0gHJx3sRsvcgIABYBiC0i+WGPzjF8GdDMSEAEOrZAFKY+xNyoCjACzjSU6BoZwL4ODYEQFHP/fHiCCH7TwMc6QC082JHAITjElhBQOrsYEL2my/rkTkBjosA/Mn2AiCLb82HEMNgNLNzCTmoKKAZcGSMlBtvyhPD/llm7whA4jwgMvefEHKwAiAAcS6A2fYWANV5KiyDC38IOehBMxS+G6Aknmp/AYB6BixO/SXkkLCaATX1DFvXAOT6W3oBYgjDf0IONQ3wAVpaodx4faYY9nydLQUAijwdkAqsADuUkEOKAAKAlAqk43QAC2wqANoJ4Zl/kh1KyKHFz+FZs4rjBPsKgHAex40/CDncNCAAaKnH27YGAIgjGP4TcrhpgB9A2hG2FABZfF06gP4UAEI6UAcAcuX6a9PEiH832koAIB3HQoYE839COlIH0AWE4xgAi22WAoiRsLj0l5CORQFBQIiR9hMAR+pgBKvZgYR0VADUlMG2qwHAMgoYARDS0SwgCCiZQ+wnAMBAzv8npKMDaQgABtlPAKSRxwIgIR12JECa+bYSALn2xlRIPZ2dR0g0HErPkMU3uMXQ5zy2EABoMh9SF+w5QqIiAAIS+QDW2kMAJHpz+y9ColUH0AGh9bJTDSCTAkBI1CIAQGhZ9hEAgUxIgx1HSLQEAEmZ9hEAKTIgTXYcIVHxJxMAMuwjAIqawVuAhERNAQCo6fYRAKEkstMIiaZPqYn2EQBYLvYYIVH1qQT7CIBpUAAIia5TuewjAJAUAEJsEFV30l0ApgCE2MGnOisCYIcREt0IADYSgJCfHUZINNH9thEAywgGFC4FIiR6PqUHA7YRgEZPQM9IdbLXCIkSDY1B3TYCsLM6YFIACIke5ZU+0zYCsHGbNzSqIJW9RkiUWL+lKWQbAVi+rq7ul+f2Y68REiV+KGmstY0A6IasYZcREj0MA/YRgGDIqmOXERI9AkGjzjYCcN2vBjawywiJHjdcPqhh5pzN9hCAmvpgE7uMkOixq5N8qlME4IfixuqzTugthRCcDkRIB5FSyjWbGnfZRgBKSps9uiHrnA6Rxe4jpGOEDFlTUubz2EYALEsaXp9RlpnmpAAQ0kGafUaZtDpnl91OEQDTlGZFTaAyM42zAQnpKDuq/ZWmnQTAMKWxZE199aghnA1ISEf5dmVdtWHaSACOHpamr9/ctJ1dR0jH2VTq3X7siHT7CEDR5FXG7y8buIFdR0jHqa4Lbvj77GL7CAAAfLW8ZqOUsISAwi4k5PCQEtaXy2uKO+vzO00Aird7G/1BoywpQRvAbiTk8PAFjNLNZc1NthOAo4elhcoq/CXDBrkpAIQcJqUVvk3HDk8LrtjQaC8BOKIgNfjxN1Vbhg1yn8NuJOTwWPhV1dajhtlQAHRT+tdv8SxnFxJy+Gzc5l1umDLQWZ/faQIwYrDb/+ZHO9axEEjI4SGltD77fte6cT/P99tOAP7y9HodQGNTs16cluIYzu4k5NBo9BobNm71NN03Y61uOwGI4P9uVd2a80/LpgAQcoh8s6puDYBOfcZGpwrA8EFu/0dfVa04/7Tsy9mdXUdOpsCgvtH/TNK1fPx11YpRBan+tSVN9hSAwgEpzV+vrFsipeTeAF3IJaeqOO2I6D5KKiNVZcN2bf4vv1pes3TEYHezbQUgpFvN3/5QW9fo1delu52j2K2EHBz1Tcaa79fU159zch+vbVOAj76qCgLQFyyq/O7qMfkUAEIOkgWfl38PQJ/8/MaQbQUggvd/S3d9efWY/GvZrYQcHP9bVvclAG9nf0+nC8D5p2Y3/3fhjnVPPXCsx+lQ3OxaQvZPMGQ2zftkx/oxZ/X1vruowt4CENJNT4NHN5ava1h88tGZl7B7O5/8vsnIy5FR/UzWcLuOZevqFzd4dEM3LE9nf1enC8CiJTU+APprH5QtpAB0DZoqANBh7cprH5Z/BED/vy+r/J39XV1iJYP6Jw30+o3sHZ9dvNChKdwnjJB9oBtWY7+z3/9ZuttZWVLq7fRdtbqiCIj+2YmNXy6vzfp+dd2i047tdSm7mZC98+0PtZ/X1IeMY4enN5WUdnoNsGsEoE+mqwmAfPW9soUUAEL2zZz3yhYCkP2zE7vk6VpdmSgOdSdp6VX/u2RBokvNZlcT0hZfwKzse+b7P29q1hsAFHfFd2pddXEnHZVR/90P9e55H+949zeX5F/P7iakLW8tLF/Q1KybZ53Qq37RkhrElABkpbnqAeS9+M72d666OO9aIQT3CCAkgpTSemn+9vkAZE6vhPqu+t6uvlc0FIB7y0cXPDmof/Ip7HZCwmwp93415IKP7gDQBGBTV32v1pUXeezwtPoVGxrdM1/d/Pb0e46iABASYeacLfMB4NRjMuu/XlmHmBSANLejHkDu7Le3LX6saGR5cqKWy64n8U6z3yh/8Z1tiwFYWenO+q787i4VgEVLaozsLFdDVW0w84V5214r+k3BH9n9JN7597xtcxs9upmbndjw7qJKsyu/u8vni44Y7Hav3+IZOjg3OXHDe+e/z5mBJJ7RDatx+CUfXbKl3Oc/dkR68Yr1DZ6u/H6tqy94/RaPB0BwS3kz5n2yc97YC3LH0QxIvPLWxzvnbSn3+QEEutr5uyUCAICsdGdObUOo/wlHZvT6Zs7Z81VFuGgKJN4wTRk4+arPf7F0bX1NdpZrR1VtsLKrf4PWHRc+qH9yTW1DqO+S1fU1Hyyu/O+Ys/v+huZA4o33v6j879K19TUArBGD3TVVtcEu/w3dtmY0K92ZX9sQ6j16ZEbmt6+fPV9VRCJNIjr8Y64XX6+O7k5Spx7pxN1XpbBxozX6W9J/wtjPxqxY39DQJ8u1q7o2WNodv0PrrgYY0C+purYh1Gvpuvq6tz/d+Z/Lz+t/Dc0iOnh9FuqarKh/Joke8z7Z8caK9Q0NAOSwge6q6m4Y/btVAJavawgAaASQ/sgz61/5+dl9L3doSjJNg8Q6umE1P/LMhlciLxv/t6wm2F2/RevOhsjvm1hVWuFPX13c2PDqe6Wzf/+LgbfRPEisM+e90tlrNjU2AkDhgJSqTdu9iEsBKK3wewF4ALgfnLlu7tgL8i5LSlD700RIrOILGOUTZ66dG3np2bTd6+3O36N1d4PkZifuLK/yD9tR7Q9NfnbjzEeLRk6hmXQM05K2+Mx45LF/bXxiZ3UgBABD8pJ3bC5rRlwLQHmV34vwCqjUSc9v+PT6ywcuG9Av6XiaCgUg1ti+s3nZlBc2ft6S+28ua27u7t+k9YSG6ds7YWfFrkCqZUkUTV459Z2Zp7wihODD6EjMIKU0bvvryn9YESEd2C9p57adPlAAAFTsCjSnpmgNTV4jfcHnFcXzP6945Rc/7TeOZkNihbc/3fnqe4srNwFARqqjfttOn68n/C6tpzRQn0xXeZPXSAWgFE1a+dy5J/c5JyVJy6PpELvjaTZKxz++6rnISys3O3FHfZMOCkArSkqbgylJWrXXZ+SUVfqDd/39h0n//PNxTwvBJ1wQO4f+kHdP/WFyWaU/CABpbkf16k1NwZ7y+7Se1FhZac4Kr8/IAuB49s2tS668MG/BWSf2/jnNiNiVz5fsmv/sf7YuibzUc3q5Kho9OigAe2F7hc/KznLtrKoNDgCA6x9aNnXVW+cen5zEnYOI/fD6jLIbH1o+veV1Xk7ijo1bvT1qTrXW0xqtqjZYAyATgHtzWbPvhoeXPzBnygkv8K4AsVfoL82bH13x55Iyb8utPk9Zpb+2p/1OrSc2Xn5OYmlppX8EAOW1D8rWjDmr73NXXpR3E82K2IXXPyx/9tV3S1dHXlqFA1K2d+eUX1sJQGmlP5CUoFb6AmY/ALj50ZWzTz8u69S8nKSjaFqkp1Na4Vt186MrXmx5nZKkVWza7g32xN+q9dRGzM5yVW7d4csAkNjoCZm/Gv/tfV++ctYrToeSSRMjPZWQbtX9avy39zV69JbNPf0D+iVWrS3xgAJwCGzd4ZP9+iRs21kdGAZAWbKmvmrClB/unzXx6KdYDyA9Ne+fMGXV/UvX1le3nBqUm7RtbYmnx86j1npyg+6sDvgSXMrOQNDKBYCnX9+89KSjMmZdfemAO2hupKfxyntlTz79+palLa+TE9UdW8t7xow/WwoAAASCVhWA1MiB6x5c/urIIe4jRo/KPIcmR3oKS9bUfXr9g8vmtDrlafabVT39d2t2aNzeGc5tu+pDIwFohmnJKyZ899C3c3/aN7uXayRNj3Q3VbWB9WPv+u5h3fhxyaSRm52wtbwq0ON/u22m2aamaOlNXmNwy28+bmR61pcvn/ViYoLalybYlg+/bsLWndGdbTaonwMXnspnuLTHFzB2nv67xeNWrG9oeaCfzEp3bq5tCDXa4ffbap69y6n0D4asnJbX553SZ/AHz5z2gqYpbpribraUexHtxSYZqQ4MzuWuwK0xDMt78S1fX7/w66qSlnOJLrXCHzR32uUa7LjQprClHgAAt101+KQn7j1mhqIIB02SAtBVWFLqRX9ddcdTr2/+vtXpLn20d9zUAFqT5nZsbfToIwA4AWDW3C3f5fRKmHj/DcMn8/Yg6QqklObjz22c2M75g30yXVur64KgAHQijR7dyEh1bK5v0ocCUAHggZnrPnMnaw/fflXhI1w+TDrX+SFnvbbl0Ykz137W6rSZneXaXFUbNOx2PZodO6G+SfclJ6pbm/3mkJY05o7JP3yY4NSSbrh80L3xLgKJLg1mcvQ/k84P+fxb26YUTVr5XuvTaW7H1qraoN+O12RrR3FoorduyPzW52Y/dvyV434x8E67Xxvpef7/0vztT4ybuPTV1iddTqU0GLJ22fWibO8kDk3k6obMbn3u+b8c98trfznoPqYDJFoj/4vzt/3t2geWvdnO+auCIavcztcWEw7i0MQg3ZBtFgnNuPfoC4t+M+RhFgZJx5xfmrPmbH6k6PFV77dxfodSF9StrXa/vpgZIR2aGKwbMqP1uUduH/nTiTcM/ytvEZLDwZJSf/y5jQ9OnLn2k3bO35Caom3ZVR+SFIAegjtZE4GgWaAbss10tduvKjhx+j1HTVFVwclC5KAxTekZP2XVn2bN3byk9XmnQ2lKTdFKamLA+WNKAAAgwakogZBVAKCNs59/avbgd548ZUaiS+1H0yYHwhcwKy67/es7Fn5TvaXdnzzuJK3E4zNi5lnpMVckczkVJRiyhqDVbEEAOGZ4WtaH/zx9Rk6vhBE0cbIvKmr86y666avxKzc01rV3/pQktcTrM61Yut6YrJInJagiqFuDTVOmtz4/sF9S4pvTT/7z6FEZ59HUSXuWrWv45Ffjv3l4+05fm2V8Dk00Jidqmxs8esw9IDFmb5MlOBWhG3KQabUtDKqKwIuTRl/5m4vzxvMOAQEAKaX12ofls665b+nLRrsBXtNEfaJL3eppNmLy6agxf59cUZBvWejd/vxNYwePfuKeo//qdCpZdIH4JaRbdeMfX3X/M2/s3snnR+dXxS7DlKWxfP1xMVFGEcixJPq1v97jRqb3nv/kqY/nZiceTVeIP8qqfKsuH//dA9+vrqtoHxSoqthpmrIy1tsgbmbKCYEMKTEQgNL6vDtZU559+Lhrxl6QexNTgrgJ+c23Pt7x/PUPLX+h0aO3L+pZioJtloX6uPCLeOp4hyZSdEMOBrDHxKCxF+SOfP4vxz+Wkqzl00ViF6/PqLj50RX3t3poR2v0RJey2R+0muNmYIw3A1AVOEwLgwHssbvF4LzkxBceOX7CWSf0vgxcTBRzA//iZTXzr3tw6bTNpc1726m32eUQW4K6DMVTo8SlkasqhGUhT8o9i4MAcMPlg47/xx+Pujc1WRtEv7E/zX6j7J6pqyc99fqWJXv7u6KgxqEppcGQJeOtbeJ9lMsCkN++LgAAuTmJrhn3HHXdL8/tf7UQgovhbZrrz/+8Yk7RpJX/Kqv0722rHksIlEqJ2nhto7gPcxUFCVY4JUjc299/fnbfwlkTj7krNydpNF3KPpRX+Zff+tiKvy34vKJkH2/xOTSxTTekP57biXkuAEVAWBL9AfTZW5soisC91w09674bht+RkqTlscV6Lr6AuWPy8xtmTnp246fW3iN6KQR2qaooNwwp4729KABtGyNVAgOxl7sEANC3T4JzUtGoX/9uTP51qqoks8V6DoYpvXPeK33pgZlr55ZX+fe1M6euCGyzJJrYYhSAfaEC6A+g177a54jC1JSHbhn5u8vO6XelqogkNln3YVkysGBRxRt/eXr9Kys3NDTsqxwgBGoBlEsJk61GATgYUgAMAJCwrzccNSwt9S+3jBp36dk5VyiKSGSTdanjBz/8snLeQ7PWzV62rqFuP28NRAp9HrYaBeBw2qcvgGzs5U5BCycemZF197hhYy87p+9lmqZksNk6M9S3PAs+r5w35fkNc79fU7+/6r0FoEoRqLAkJFuOAtARnAByAezXuQf2S0oY/7vCS66/fOBvkxO1XDZb9PAFzB2z397+xvSXi9/eXNZ8oMp9gwDKJRBky1EAop0W5AHYb96fluJQr/3VwJ/c8duCS/Nzkk4TYt/RA9k3UsLaucu/ZPrLm9587s1tXzQ16wfajMMHoBxguE8B6FyyAOTsrz7Qwpmje2VdfemAX1x5Ud6liQlqfzbdgQmGzOq3PtmxYPa87e988m31wazICwKoAOJ3Qg8FoHvarkUIXAd6sztZU66+dMDoKy7IPee0ozPP1TQljU24G9O0PEvW1H/66id+qQsAAAK8SURBVLulC19aULrUe3D77oVaOT7zfApAtwpB9sFEBADQO8Op/fqivNFXXZT3s+NHZpzpcCip8dhwhmE1LV1bv/j1D8sXvfFh2deVtcGDfaRxEEAVgBo6PgWgJ5EeEYKDfo52utuhXPGz/sNOPDLrjF+e2++kjFTnkbFaM5AS0tOsb3xvceU3Xyzb9fV/F+5YXdsQOpQHajYDqATQQFOjAPRkkiNCkH6obXzy0ZnpZxzX64SfnND7yDOOzToiNcUxSgio9nR4aXl8Rsn3q+tXLfyqavkXy2qWfPdD3aE6r4w4fFVEAAgFwDZokfSg18GmB+0pyEtJOP+0PiOHD3Yf97NTswfk5iQOS3RpA3talCAlZCBoVlTWBjd8+l3VltUbm1YsWrZr7Q8bGr2H+ZGBSIhfB0CnKVEA7E5KRAjSgY6N6EPyUhLOHN1rQJ8s19DC/JT80UdkZPbvk5DjTnbkOx1KTmf2q25Y9Z5mo7SqNrBjxbqGmtUlTVurawPFi5fUbt9c7g108ONNAPUIF/W8NBkKQKy2eSrCk4o6LAbtGdQ/2XXMiLSMrFRnWnKSlu5yKulOh5LZOz0hvU+W05Ga4lBTEjVHcorqcDkUBwAEdUtv9pq612/oTV7drK4N6bsaAg0h3aoLhqyGZp/RUNsUaly5vrF+647maE+uMSMhfj2AJrCoRwGIQzFoORLi5LqDEWdvpNNTAMhunADSImKQEqkhxAJGJKT3RBw+wK6mAJAD44oIQcvhskGfycgI70W4at8MwM+upACQ6PRXAsLblyVF/uuKRA6iGxw9FHF2f2RU90cOi11FASBdnz44I4LgiKQPrQ8V4SXNInIorfpfRpxWtvq3GQndWx96xOFDkYMQQgghhBBCCCGEEEIIIYQQQgghhBBCCCGEEEIIIYQQQgghhBBCCCGERJn/D0LnXZx+nbGWAAAAAElFTkSuQmCC'); } .notice.show { opacity: 1; } .notice.hide { opacity: 0; } /* http://programmingnotes.org/ */ |
4. More Examples
Below are more examples demonstrating the use of ‘Notice.js‘. Don’t forget to include the module when running the examples!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 |
<!-- // ============================================================================ // Author: Kenneth Perkins // Date: Oct 31, 2020 // Taken From: http://programmingnotes.org/ // File: Notification.html // Description: Demonstrates how to display a notification div message to // the page with icons. // ============================================================================ --> <!DOCTYPE html> <html> <head> <meta charset="utf-8"/> <title>My Programming Notes Notification Display Demo</title> <style> .button { padding: 8px; background-color: #d2d2d2; height:100%; text-align:center; text-decoration:none; color:black; display: flex; justify-content: center; align-items: center; flex-direction: column; border-radius: 15px; cursor: pointer; } .button:hover { background-color:#bdbdbd; } .buttonSection { border-top: 1px solid #a3a3a3; border-bottom: 1px solid #a3a3a3; padding:8px; margin-bottom:10px; text-align:center; margin-top: 10px; } .inline { display:inline-block; } .main { text-align:center; margin-left:auto; margin-right:auto; } </style> <!-- // Include module --> <link type="text/css" rel="stylesheet" href="./Notice.css"> <script type="text/javascript" src="./Notice.js"></script> </head> <body> <div class="main"> <div class="notice-message notice hide"></div> <br /> <div class="notice"> Success </div> <br /> <div class="notice warning"> Warning </div> <br /> <div class="notice error"> Error </div> <br /> <div class="buttonSection"> <div id="btnSuccessMessage" class="inline button"> Success Message </div> <div id="btnWarningMessage" class="inline button"> Warning Message </div> <div id="btnErrorMessage" class="inline button"> Error Message </div> <div style="margin-top: 5px;"> Click a button to see the different message styles! </div> </div> </div> <script> document.addEventListener('DOMContentLoaded', function(eventLoaded) { document.querySelector('#btnSuccessMessage').addEventListener('click', (e) => { Notice.display(document.querySelector('.notice-message'), 'Success!', Notice.type.success); }); document.querySelector('#btnWarningMessage').addEventListener('click', (e) => { Notice.display(document.querySelector('.notice-message'), 'Warning!', Notice.type.warning); }); document.querySelector('#btnErrorMessage').addEventListener('click', (e) => { Notice.display(document.querySelector('.notice-message'), 'Error!', Notice.type.error); }); }); </script> </body> </html><!-- // http://programmingnotes.org/ --> |
QUICK NOTES:
The highlighted lines are sections of interest to look out for.
The code is heavily commented, so no further insight is necessary. If you have any questions, feel free to leave a comment below.
JavaScript || How To Get All Unique Values In An Array & Remove Duplicates Using Vanilla JavaScript
The following is a module with functions which demonstrates how to get all distinct values in an array & remove duplicates from a simple and object array.
The functions on this page allows for an optional selector function as a parameter, which makes them general enough to work on arrays of any type.
1. Simple Array
The example below demonstrates the use of ‘Utils.arrayUnique‘ to get unique values from a simple array.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
// Simple Array <script> (() => { // Simple array let fruits = [ 'apple', 'orange', 'apple', 'watermelon', 'apple', 'peach', 'orange', 'watermelon', 'grape' ]; // Get unique items from an array let result = Utils.arrayUnique(fruits); result.forEach(item => { console.log(item); }); })(); </script> // expected output: /* apple orange watermelon peach grape */ |
2. Object Array
The example below demonstrates the use of ‘Utils.arrayUnique‘ to get unique values from an object array.
In this example, a selector is used, which extracts the value to be used in the evaluation.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
// Object Array <script> (() => { // Object array let products = [{ 'id': 1, 'title': 'iPad 4 Mini', 'price': 500.01, 'inventory': 2, 'categories': ['Electronics'], }, { 'id': 2, 'title': 'H&M T-Shirt White', 'price': 10.99, 'inventory': 10, 'categories': ['Clothing'], }, { 'id': 3, 'title': 'Charli XCX - Sucker CD', 'price': 19.99, 'inventory': 5, 'categories': ['Music', 'Electronics'] } ]; // Get unique items from an object array let result = Utils.arrayUnique(products, (product) => product.categories); result.forEach(item => { console.log(item); }); })(); </script> // expected output: /* Electronics Clothing Music */ |
3. Mixed Array
The example below demonstrates the use of ‘Utils.arrayUnique‘ to get unique values from a mixed array.
In this example, a selector is used, which extracts the value to be used in the evaluation.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
// Mixed Array <script> (() => { // Mixed array let mixedArray = [ [0, 'Aluminium', 0, 'Francis'], [1, 'Argon', 1, 'Ada'], [2, 'Brom', 2, 'John'], [3, 'Cadmium', 9, 'Marie'], [4, 'Fluor', 12, 'Marie'], [5, 'Gold', 1, 'Ada'], [6, 'Kupfer', 4, 'Ines'], [7, 'Krypton', 4, 'Joe'], [8, 'Sauerstoff', 0, 'Marie'], [9, 'Zink', 5, 'Max'] ]; // Get unique items from an array at index 2 let result = Utils.arrayUnique(mixedArray, (item) => item[2]); result.forEach(item => { console.log(item); }); })(); </script> // expected output: /* 0 1 2 9 12 4 5 */ |
4. Utils Namespace
The following is the Utils.js Namespace. Include this in your project to start using!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
// ============================================================================ // Author: Kenneth Perkins // Date: Oct 19, 2020 // Taken From: http://programmingnotes.org/ // File: Utils.js // Description: Javascript that handles general utility functions // ============================================================================ /** * NAMESPACE: Utils * USE: Handles general utility functions. */ var Utils = Utils || {}; (function(namespace) { 'use strict'; // Property to hold public variables and functions let exposed = namespace; /** * FUNCTION: arrayUnique * USE: Returns distinct elements from a sequence. * @param array: The array to remove duplicate elements from. * @param selector: Optional. A transform function to extract values from each element. * @return: An array that contains distinct elements from the source sequence. */ exposed.arrayUnique = (array, selector = null) => { if (typeof selector !== 'function') { selector = (item) => item; } let value = array .reduce((acc, item) => acc.concat(selector.call(array, item)), []) .filter((value, index, self) => self.indexOf(value) === index); return value; } (function (factory) { if (typeof define === 'function' && define.amd) { define([], factory); } else if (typeof exports === 'object') { module.exports = factory(); } }(function() { return namespace; })); }(Utils)); // http://programmingnotes.org/ |
QUICK NOTES:
The highlighted lines are sections of interest to look out for.
The code is heavily commented, so no further insight is necessary. If you have any questions, feel free to leave a comment below.
JavaScript || Circular Array – How To Index Into Array As If It Is Circular Using Vanilla JavaScript
The following is a module with functions which demonstrates how to index into an array as if it is circular using Vanilla JavaScript.
This function adjusts a range as circular and ‘wraps around’ the value to become in bounds.
1. Circular Array
The example below demonstrates the use of ‘Utils.circularWrap‘ to index into an array as if it is circular.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
// Circular Array <script> (() => { let words = ['this', 'and', 'that']; for (let index = -9; index <= 10; ++index) { let adjusted = Utils.circularWrap(index, words.length); console.log(`Index: ${index}, Adjusted Index: ${adjusted}, Word: ${words[adjusted]}`); } })(); </script> // expected output: /* Index: -9, Adjusted Index: 0, Word: this Index: -8, Adjusted Index: 1, Word: and Index: -7, Adjusted Index: 2, Word: that Index: -6, Adjusted Index: 0, Word: this Index: -5, Adjusted Index: 1, Word: and Index: -4, Adjusted Index: 2, Word: that Index: -3, Adjusted Index: 0, Word: this Index: -2, Adjusted Index: 1, Word: and Index: -1, Adjusted Index: 2, Word: that Index: 0, Adjusted Index: 0, Word: this Index: 1, Adjusted Index: 1, Word: and Index: 2, Adjusted Index: 2, Word: that Index: 3, Adjusted Index: 0, Word: this Index: 4, Adjusted Index: 1, Word: and Index: 5, Adjusted Index: 2, Word: that Index: 6, Adjusted Index: 0, Word: this Index: 7, Adjusted Index: 1, Word: and Index: 8, Adjusted Index: 2, Word: that Index: 9, Adjusted Index: 0, Word: this Index: 10, Adjusted Index: 1, Word: and */ |
2. Utils Namespace
The following is the Utils.js Namespace. Include this in your project to start using!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
// ============================================================================ // Author: Kenneth Perkins // Date: Oct 7, 2020 // Taken From: http://programmingnotes.org/ // File: Utils.js // Description: Javascript that handles general utility functions // ============================================================================ /** * NAMESPACE: Utils * USE: Handles general utility functions. */ var Utils = Utils || {}; (function(namespace) { 'use strict'; // Property to hold public variables and functions let exposed = namespace; /** * FUNCTION: circularWrap * USE: Adjusts a range as circular and 'wraps around' the value to become in bounds * @param left: The current number, or the 'numerator' * @param right: The upper bound maximum range number, or the 'denominator' * @return: The adjusted value according to the denominator */ exposed.circularWrap = (left, right) => { return ((left % right) + right) % right; } (function (factory) { if (typeof define === 'function' && define.amd) { define([], factory); } else if (typeof exports === 'object') { module.exports = factory(); } }(function() { return namespace; })); }(Utils)); // http://programmingnotes.org/ |
QUICK NOTES:
The highlighted lines are sections of interest to look out for.
The code is heavily commented, so no further insight is necessary. If you have any questions, feel free to leave a comment below.
C++ || How To Find All Combinations Of Well-Formed Brackets Using C++
The following is a program with functions which demonstrates how to find all combinations of well-formed brackets.
The task is to write a function Brackets(int n) that prints all combinations of well-formed brackets from 1…n. For example, Brackets(3), the output would be:
()
(()) ()()
((())) (()()) (())() ()(()) ()()()
The number of possible combinations is the Catalan number of N pairs C(n).
1. Find All Well-Formed Brackets
The example below demonstrates the use of the ‘brackets‘ function to find all the well-formed bracket combinations.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 |
// ============================================================================ // Author: Kenneth Perkins // Date: Oct 7, 2020 // Taken From: http://programmingnotes.org/ // File: generateParenthesis.cpp // Description: Generate all combinations of well-formed brackets from 1…n // ============================================================================ #include <iostream> #include <vector> #include <string> struct result { int pair; std::string combination; }; struct symbols { std::string open; std::string close; }; std::string buildBrackets(std::string output, int open, int close, int pair, symbols symbols) { if ((open == pair) && (close == pair)) { return output; } std::string result = ""; if (open < pair) { std::string openCombo = buildBrackets(output + symbols.open, open + 1, close, pair, symbols); if (openCombo.length() > 0) { result += (result.length() > 0 ? ", " : "") + openCombo; } } if (close < open) { std::string closeCombo = buildBrackets(output + symbols.close, open, close + 1, pair, symbols); if (closeCombo.length() > 0) { result += (result.length() > 0 ? ", " : "") + closeCombo; } } return result; } /** * FUNCTION: brackets * USE: Returns all combinations of well-formed brackets from 1...n * @param pairs: The number of bracket combinations to generate. * @param open: Optional. The 'open bracket' symbol. * @param close: Optional. The 'close bracket' symbol. * @return: An array of bracket combination info. */ std::vector<result> brackets(int pairs, std::string open = "(", std::string close = ")") { std::vector<result> results; symbols symbols{open, close}; for (int pair = 1; pair <= pairs; ++pair) { result result{pair, buildBrackets("", 0, 0, pair, symbols)}; results.push_back(result); } return results; } int main() { std::vector<result> results = brackets(4); for (auto const &result : results) { std::cout << "Pair: " << result.pair << ", Combination: " << result.combination << std::endl; } std::cin.get(); return 0; }// http://programmingnotes.org/ |
QUICK NOTES:
The highlighted lines are sections of interest to look out for.
The code is heavily commented, so no further insight is necessary. If you have any questions, feel free to leave a comment below.
Once compiled, you should get this as your output
Pair: 1, Combination: ()
Pair: 2, Combination: (()), ()()
Pair: 3, Combination: ((())), (()()), (())(), ()(()), ()()()
Pair: 4, Combination: (((()))), ((()())), ((())()), ((()))(), (()(())), (()()()), (()())(), (())(()), (())()(), ()((())), ()(()()), ()(())(), ()()(()), ()()()()
JavaScript || How To Find All Combinations Of Well-Formed Brackets Using Vanilla JavaScript
The following is a module with functions which demonstrates how to find all combinations of well-formed brackets.
The task is to write a function Brackets(int n) that prints all combinations of well-formed brackets from 1…n. For example, Brackets(3), the output would be:
()
(()) ()()
((())) (()()) (())() ()(()) ()()()
The number of possible combinations is the Catalan number of N pairs C(n).
1. Find All Well-Formed Brackets
The example below demonstrates the use of ‘Utils.brackets‘ to find all the well-formed bracket combinations.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
// Find All Well-Formed Brackets <script> (() => { let results = Utils.brackets(4); results.forEach((result) => { console.log(`Pair: ${result.pair}, Combination: ${result.combination}`); }); })(); </script> // expected output: /* Pair: 1, Combination: () Pair: 2, Combination: (()), ()() Pair: 3, Combination: ((())), (()()), (())(), ()(()), ()()() Pair: 4, Combination: (((()))), ((()())), ((())()), ((()))(), (()(())), (()()()), (()())(), (())(()), (())()(), ()((())), ()(()()), ()(())(), ()()(()), ()()()() */ |
2. Utils Namespace
The following is the Utils.js Namespace. Include this in your project to start using!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 |
// ============================================================================ // Author: Kenneth Perkins // Date: Oct 6, 2020 // Taken From: http://programmingnotes.org/ // File: Utils.js // Description: Javascript that handles general utility functions // ============================================================================ /** * NAMESPACE: Utils * USE: Handles general utility functions. */ var Utils = Utils || {}; (function(namespace) { 'use strict'; // Property to hold public variables and functions let exposed = namespace; /** * FUNCTION: brackets * USE: Returns all combinations of well-formed brackets from 1...n * @param pairs: The number of bracket combinations to generate. * @param open: Optional. The 'open bracket' symbol. * @param close: Optional. The 'close bracket' symbol. * @return: An array of bracket combination info. */ exposed.brackets = (pairs, open = '(', close = ')') => { let results = []; let symbols = { open: open, close: close, }; for (let pair = 1; pair <= pairs; ++pair) { results.push({ pair: pair, combination: buildBrackets('', 0, 0, pair, symbols), }); } return results; } let buildBrackets = (output, open, close, pair, symbols) => { if ((open === pair) && (close === pair)) { return output; } let result = ''; if (open < pair) { let openCombo = buildBrackets(output + symbols.open, open + 1, close, pair, symbols); if (openCombo.length > 0) { result += (result.length > 0 ? ', ' : '') + openCombo; } } if (close < open) { let closeCombo = buildBrackets(output + symbols.close, open, close + 1, pair, symbols); if (closeCombo.length > 0) { result += (result.length > 0 ? ', ' : '') + closeCombo; } } return result; } (function (factory) { if (typeof define === 'function' && define.amd) { define([], factory); } else if (typeof exports === 'object') { module.exports = factory(); } }(function() { return namespace; })); }(Utils)); // http://programmingnotes.org/ |
QUICK NOTES:
The highlighted lines are sections of interest to look out for.
The code is heavily commented, so no further insight is necessary. If you have any questions, feel free to leave a comment below.
JavaScript || How To Calculate Nth Catalan Number Using Vanilla JavaScript
In combinatorial mathematics, a Catalan number forms a sequence of natural numbers that occur in various counting problems. It can be used to determine how many different ways to split something up.
The following is a module with functions which demonstrates how to calculate nth Catalan number.
1. Calculate Nth Catalan Number
The example below demonstrates the use of ‘Utils.catalan‘ to calculate nth Catalan number.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
// Calculate Nth Catalan Number <script> (() => { for (let number = 0; number <= 10; ++number) { console.log(`Number: ${number}, Catalan: ${Utils.catalan(number)}`); } })(); </script> // expected output: /* Number: 0, Catalan: 1 Number: 1, Catalan: 1 Number: 2, Catalan: 2 Number: 3, Catalan: 5 Number: 4, Catalan: 14 Number: 5, Catalan: 42 Number: 6, Catalan: 132 Number: 7, Catalan: 429 Number: 8, Catalan: 1430 Number: 9, Catalan: 4862 Number: 10, Catalan: 16796 */ |
2. Utils Namespace
The following is the Utils.js Namespace. Include this in your project to start using!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
// ============================================================================ // Author: Kenneth Perkins // Date: Oct 6, 2020 // Taken From: http://programmingnotes.org/ // File: Utils.js // Description: Javascript that handles general utility functions // ============================================================================ /** * NAMESPACE: Utils * USE: Handles general utility functions. */ var Utils = Utils || {}; (function(namespace) { 'use strict'; // Property to hold public variables and functions let exposed = namespace; /** * FUNCTION: catalan * USE: Calculates the catalan number for the number in question * @param n: The number to calculate the catalan number. * @return: The catalan number for the number in question. */ exposed.catalan = (n) => { n = Math.max(0, n); let result = Array(n + 1); result[0] = result[1] = 1; for (let x = 2; x <= n; ++x) { result[x] = 0; for (let y = 0; y < x; ++y) { result[x] += result[y] * result[x - y - 1]; } } return result[n]; } (function (factory) { if (typeof define === 'function' && define.amd) { define([], factory); } else if (typeof exports === 'object') { module.exports = factory(); } }(function() { return namespace; })); }(Utils)); // http://programmingnotes.org/ |
QUICK NOTES:
The highlighted lines are sections of interest to look out for.
The code is heavily commented, so no further insight is necessary. If you have any questions, feel free to leave a comment below.