Skip to content

my-lambda-projects/lambda-prep

This branch is up to date with Web-Dev-Collaborative/lambda-prep:master.

Folders and files

NameName
Last commit message
Last commit date
Apr 5, 2021
Apr 4, 2021
Apr 4, 2021
May 13, 2021
Apr 4, 2021
Apr 4, 2021
Apr 5, 2021
Apr 5, 2021
Apr 4, 2021
Apr 4, 2021
Apr 5, 2021
Apr 4, 2021
Apr 5, 2021
Apr 4, 2021
Mar 30, 2021
Apr 5, 2021
Mar 30, 2021
Apr 3, 2021
Apr 4, 2021
Apr 5, 2021
Apr 4, 2021
Apr 4, 2021
Apr 4, 2021
Apr 4, 2021
Apr 4, 2021
Apr 4, 2021
Apr 3, 2021
Apr 4, 2021
Apr 4, 2021
Apr 4, 2021
Apr 4, 2021
Apr 5, 2021
Mar 30, 2021

Repository files navigation

Prep-Work

0.) Links:

HTML TAG EXAMPLES Navigation Playground Quiz Me Text-Tools Github HTML FilePreviewersimple-sidebar-template My Blog Posts

Name Hyperlink
OKTA https://lambdaschoolsso.okta.com/login/login.htm?fromURI=%2Fapp%2FUserHome
Calendar https://calendar.google.com/calendar/u/0/embed?src=c_2q0kvam9h9k5i6t40qp5n18dh8@group.calendar.google.com
Slack https://app.slack.com/client/T4JUEB3ME/G01QG65CN75
Prep Work https://apply.lambdaschool.com/courses/web/

google-analytics

3.) Pre-Course Work Edit epic-hawking-rdij1

.
├── README.html
├── README.md
├── SUMMARY.html
├── SUMMARY.md
├── codeswing.json
├── comparison.png
├── demo.html
├── directory.html
├── index.html
├── javascript-practice
│   ├── 00_expressions_variables
│   │   ├── exercises
│   │   │   ├── A_executing_code_exercise
│   │   │   │   ├── README.html
│   │   │   │   ├── README.md
│   │   │   │   
│   │   │   ├── B_expressions_exercise
│   │   │   │   ├── README.html
│   │   │   │   ├── README.md
│   │   │   │   
│   │   │   ├── C_variables_exercise
│   │   │   │   ├── README.html
│   │   │   │   ├── README.md
│   │   │   │   
│   │   │   ├── D_string_indexing_and_methods_exercise
│   │   │   │   ├── README.html
│   │   │   │   ├── README.md
│   │   │   │   
│   │   │   
│   │   ├──
│   │   └── solutions
│   │       ├── A_executing_code_solution
│   │       │   ├── age.js
│   │       │   ├── greeting.js
│   │       │   ├──
│   │       │   ├── thirsty.js
│   │       │   └── whoami.js
│   │       ├── B_expressions_solution
│   │       │   ├── boolean-expressions.js
│   │       │   ├── comparisons.js
│   │       │   ├── number-expressions.js
│   │       │   ├──
│   │       │   └── string-expressions.js
│   │       ├── C_variables_solution
│   │       │   ├── four.js
│   │       │   ├── one.js
│   │       │   ├──
│   │       │   ├── three.js
│   │       │   ├── two.js
│   │       │   └── zero.js
│   │       ├── D_string_indexing_and_methods_solution
│   │       │   ├── a-tedious-task.js
│   │       │   ├── dare-to-decipher.js
│   │       │   ├── proper-patterns.js
│   │       │   ├──
│   │       │   └── small-string-snippets.js
│   │       
│   ├── 01_conditionals
│   │   ├── exercises
│   │   │   ├── A_conditionals_exercise
│   │   │   │   ├── README.html
│   │   │   │   ├── README.md
│   │   │   │   
│   │   │   
│   │   ├──
│   │   └── solutions
│   │       ├── A_conditionals_solution
│   │       │   ├── one.js
│   │       │   ├──
│   │       │   ├── three.js
│   │       │   ├── two.js
│   │       │   └── zero.js
│   │       
│   ├── 02_functions
│   │   ├── exercises
│   │   │   ├── A_functions_exercise
│   │   │   │   ├── README.html
│   │   │   │   ├── README.md
│   │   │   │   
│   │   │   ├── B_functions_exercise
│   │   │   │   ├── README.html
│   │   │   │   ├── README.md
│   │   │   │   
│   │   │   ├── C_functions_exercise
│   │   │   │   ├── README.html
│   │   │   │   ├── README.md
│   │   │   │   
│   │   │   
│   │   ├──
│   │   └── solutions
│   │       ├── A_functions_solution
│   │       │   ├── average.js
│   │       │   ├── ends-with-t.js
│   │       │   ├── half.js
│   │       │   ├── is-div-by-4.js
│   │       │   ├── is-long.js
│   │       │   ├── keep-it-quiet.js
│   │       │   ├──
│   │       │   ├── snippet-0-1.js
│   │       │   ├── snippet-0-2.js
│   │       │   ├── snippet-0-3.js
│   │       │   └── snippet-0-4.js
│   │       ├── B_functions_solution
│   │       │   ├── ends-in-ly.js
│   │       │   ├── funny-sound.js
│   │       │   ├── longer.js
│   │       │   ├── one-or-none.js
│   │       │   ├── parity.js
│   │       │   ├──
│   │       │   ├── starts-with-r.js
│   │       │   ├── string-size.js
│   │       │   └── wacky-word.js
│   │       ├── C_functions_solution
│   │       │   ├── average-of-four.js
│   │       │   ├── case-changer.js
│   │       │   ├── contains.js
│   │       │   ├── divisible.js
│   │       │   ├── in-range.js
│   │       │   ├── larger.js
│   │       │   ├── number-change.js
│   │       │   
│   │       
│   ├── 03_loops
│   │   ├── exercises
│   │   │   ├── A_loops_exercise
│   │   │   │   ├── README.html
│   │   │   │   ├── README.md
│   │   │   │   
│   │   │   ├── B_loops_exercise
│   │   │   │   ├── README.html
│   │   │   │   ├── README.md
│   │   │   │   
│   │   │   ├── C_loops_exercise
│   │   │   │   ├── README.html
│   │   │   │   ├── README.md
│   │   │   │   
│   │   │   
│   │   ├──
│   │   └── solutions
│   │       ├── A_loops_solution
│   │       │   ├── count-up.js
│   │       │   ├── evens.js
│   │       │   ├── min-to-max.js
│   │       │   ├── one-to-four.js
│   │       │   ├──
│   │       │   ├── snippet-1.js
│   │       │   ├── snippet-2.js
│   │       │   ├── snippet-3.js
│   │       │   ├── snippet-4.js
│   │       │   ├── snippet-5.js
│   │       │   └── string-iterate.js
│   │       ├── B_loops_solution
│   │       │   ├── div-by-either.js
│   │       │   ├── five-multiples-of.js
│   │       │   ├── no-ohs.js
│   │       │   ├── odd-sum.js
│   │       │   ├── product-up-to.js
│   │       │   ├──
│   │       │   ├── string-repeater.js
│   │       │   └── sum-up-to.js
│   │       ├── C_loops_solution
│   │       │   ├── censor-e.js
│   │       │   ├── divisible-range.js
│   │       │   ├── fizz-buzz.js
│   │       │   ├── raise-power.js
│   │       │   ├── remove-capitals.js
│   │       │   ├── reverse-iterate.js
│   │       │   
│   │       
│   ├── 04_arrays
│   │   ├── exercises
│   │   │   ├── A_arrays_exercise
│   │   │   │   ├── README.html
│   │   │   │   ├── README.md
│   │   │   │   
│   │   │   ├── B_arrays_exercise
│   │   │   │   ├── README.html
│   │   │   │   ├── README.md
│   │   │   │   
│   │   │   ├── C_arrays_exercise
│   │   │   │   ├── README.html
│   │   │   │   ├── README.md
│   │   │   │   
│   │   │   
│   │   ├──
│   │   └── solutions
│   │       ├── A_arrays_solution
│   │       │   ├── bleep-vowels.js
│   │       │   ├── divisors.js
│   │       │   ├── filter-long-words.js
│   │       │   ├── num-odds.js
│   │       │   ├──
│   │       │   ├── stay-positive.js
│   │       │   ├── strings-to-lengths.js
│   │       │   └── total.js
│   │       ├── B_arrays_solution
│   │       │   ├── choose-divisibles.js
│   │       │   ├── make-acronym.js
│   │       │   ├── maximum.js
│   │       │   ├── reverse-array.js
│   │       │   ├──
│   │       │   ├── word-count.js
│   │       │   └── your-average-function.js
│   │       ├── C_arrays_solution
│   │       │   ├── alternating-caps.js
│   │       │   ├── common-elements.js
│   │       │   ├── lengthiest-word.js
│   │       │   ├── number-range.js
│   │       │   ├── remove-short-words.js
│   │       │   
│   │       
│   ├── 05_nesting
│   │   ├── exercises
│   │   │   ├── A_nested_loops_exercise
│   │   │   │   ├── README.html
│   │   │   │   ├── README.md
│   │   │   │   
│   │   │   ├── B_two_dimensional_arrays_exercise
│   │   │   │   ├── README.html
│   │   │   │   ├── README.md
│   │   │   │   
│   │   │   ├── C_more_problems_exercise
│   │   │   │   ├── README.html
│   │   │   │   ├── README.md
│   │   │   │   
│   │   │   
│   │   ├──
│   │   └── solutions
│   │       ├── A_nested_loops_solution
│   │       │   ├── pair-print.js
│   │       │   ├── print-combinations.js
│   │       │   ├──
│   │       │   ├── snippet-1.js
│   │       │   ├── snippet-2.js
│   │       │   ├── snippet-3.js
│   │       │   ├── snippet-4.js
│   │       │   ├── snippet-5.js
│   │       │   └── two-sum.js
│   │       ├── B_two_dimensional_arrays_solution
│   │       │   ├── make-matrix.js
│   │       │   ├── print-2d.js
│   │       │   ├──
│   │       │   ├── total-product.js
│   │       │   ├── two-sum-pairs.js
│   │       │   └── zipper.js
│   │       ├── C_more_problems_solution
│   │       │   ├── remove-dupes.js
│   │       │   ├── remove-first-vowel.js
│   │       │   ├── remove-vowels.js
│   │       │   ├──
│   │       │   ├── shorten-long-words.js
│   │       │   └── spam.js
│   │       
│   ├── 06_decomposition_pattern
│   │   ├── A_decomposing_problems_exercise
│   │   │   ├── README.html
│   │   │   ├── README.md
│   │   │   
│   │   ├── B_decomposing_problems_exercise
│   │   │   ├── README.html
│   │   │   ├── README.md
│   │   │   
│   │   ├── C_decomposing_problems_exercise
│   │   │   ├── README.html
│   │   │   ├── README.md
│   │   │   
│   │   
│   ├── 07_objects
│   │   ├── A_objects_exercise
│   │   │   ├── README.html
│   │   │   ├── README.md
│   │   │   
│   │   ├── B_objects_exercise
│   │   │   ├── README.html
│   │   │   ├── README.md
│   │   │   
│   │   ├── C_objects_exercise
│   │   │   ├── README.html
│   │   │   ├── README.md
│   │   │   
│   │   
│   ├── 08_higher_order_functions
│   │   ├── A_native_callback_methods_exercise
│   │   │   ├── README.html
│   │   │   ├── README.md
│   │   │   
│   │   ├── B_native_callback_methods_exercise
│   │   │   ├── README.html
│   │   │   ├── README.md
│   │   │   
│   │   
│   
├── js.js
├── one-of-every-tag.html
├── readme
│   ├── README.html
│   ├── README_files
│   │   ├── katex.min.css
│   │   
│   
├── resources.html
├── resources.md
├── script.js
├── style.css
└── tree.md

66 directories, 241 files





WEEK 1
Introduction to JavaScript (Part 1) {ignore=true}


Expression Learning Objectives Intro to Functions Learning Objectives

Control Flow and Array Learning Objectives

Intermediate Functions Learning Objectives


WEEK-01 DAY-1
Function Introduction {ignore=true}


Expression Learning Objectives

Below is a complete list of the terminal learning objectives for this lesson. When you complete this lesson, you should be able to perform each of the following objectives. These objectives capture how you may be evaluated on the assessment for this lesson.

  1. Given a working REPL interface, write and execute a statement that will print "hello world" using console.log

  2. Identify that strings are a list of characters defined by using double or single quotes

  3. Given an arithmetic expression using +, -, *, /, %, compute its value

  4. Given an expression, predict if its value is NaN

  5. Construct the truth tables for &&, ||, !

  6. Given an expression consisting of >, >=, ===, <, <=, compute it's value

  7. Apply De Morgan's law to a boolean expression

  8. Given an expression that utilizes operator precedence, compute its value

  9. Given an expression, use the grouping operator to change it's evaluation

  10. Given expressions using == and ===, compute their values

  11. Given a code snippet using postfix ++, postfix --, +=, -=, /=, *=, predict the value of labeled lines

  12. Create and assign a variable using let to a string, integer, and a boolean. Read its value and print to the console.l learning objectives for this lesson. When you complete this lesson, you should be able to perform each of the following objectives. These objectives capture how you may be evaluated on the assessment for this lesson.

  13. Given a working REPL interface, write and execute a statement that will print "hello world" using console.log

  14. Identify that strings are a list of characters defined by using double or single quotes

  15. Given an arithmetic expression using +, -, *, /, %, compute its value

  16. Given an expression, predict if its value is NaN

  17. Construct the truth tables for &&, ||, !

  18. Given an expression consisting of >, >=, ===, <, <=, compute it's value

  19. Apply De Morgan's law to a boolean expression

  20. Given an expression that utilizes operator precedence, compute its value

  21. Given an expression, use the grouping operator to change it's evaluation

  22. Given expressions using == and ===, compute their values

  23. Given a code snippet using postfix ++, postfix --, +=, -=, /=, *=, predict the value of labeled lines

  24. Create and assign a variable using let to a string, integer, and a boolean. Read its value and print to the console.


Intro to Functions Learning Objectives

Below is a complete list of the terminal learning objectives for this lesson. When you complete this lesson, you should be able to perform each of the following objectives. These objectives capture how you may be evaluated on the assessment for this lesson.

  1. Define a function using function declaration

  2. Define a function that calculates the average of two numbers, call it, pass in arguments, and print it's return value

  3. Identify the difference between parameters vs argument terminal learning objectives for this lesson. When you complete this lesson, you should be able to perform each of the following objectives. These objectives capture how you may be evaluated on the assessment for this lesson.

  4. Define a function using function declaration

  5. Define a function that calculates the average of two numbers, call it, pass in arguments, and print it's return value

  6. Identify the difference between parameters vs arguments


Hello World

Hey Programmer! Welcome to the JavaScript module. In the next few sections, we'll be learning the fundamentals of the JavaScript programming language. If it's your first time programming, don't worry; we designed this course especially for you. We'll have you executing your first lines of code in no time!

When you finish this article, you should be able to:

  • use the console.log command to print out messages
  • use double slashes (//) to write code comments

Getting visual feedback in your programs

The first command we'll learn in JavaScript is console.log. This command is used to print something onto the screen. As we write our first lines of code, we'll be using console.log frequently as a way to visually see the output of our programs. Let's write our first program:

console.log("hello world");
console.log("how are you?");

Executing the program above would print out the following:

hello world
how are you?

Nothing too ground breaking here, but pay close attention to the exact way we wrote the program. In particular, notice how we lay out the periods, parentheses, and quotation marks. We'll also terminate lines with semicolons (;).

Depending on how you structure your code, sometimes you'll be able to omit semicolons at the end of lines. For now, you'll want to include them just as we do.

Syntax

We refer to the exact arrangement of the symbols, characters, and keywords as syntax. These details matter - your computer will only be able to "understand" proper JavaScript syntax. A programming language is similar to a spoken language. A spoken language like English has grammar rules that we should follow in order to be understood by fellow speakers. In the same way, a programming language like JavaScript has syntax rules that we ought to follow!

As you write your first lines of code in this new language, you may make many syntax errors. Don't get frustrated! This is normal - all new programmers go through this phase. Every time we recognize an error in our code, we have an opportunity to reinforce your understanding of correct syntax. Adopt a growth mindset and learn from your mistakes.

Additionally, one of the best things about programming is that we can get such immediate feedback from our creations. There is no penalty for making a mistake when programming. Write some code, run the code, read the errors, fix the errors, rinse and repeat!

Code comments

Occasionally we'll want to leave comments or notes in our code. Commented lines will be ignored by our computer. This means that we can use comments to write plain english or temporarily avoid execution of some JavaScript lines. The proper syntax for writing a comment is to begin the line with double forward slashes (//):

// let's write another program!!!
console.log("hello world");

// console.log("how are you?");

console.log("goodbye moon");

The program above would only print:

hello world
goodbye moon

Comments are useful when annotating pieces of code to offer an explanation of how the code works. We'll want to strive to write straightforward code that is self-explanatory when possible, but we can also use comments to add additional clarity. The real art of programming is to write code so elegantly that it is easy to follow.

"Simplicity is prerequisite for reliability." — Edsger W. Dijkstra

Remember

  • console.log can be used to print to the screen
  • using // at the front of a line will turn it into a comment; comments are ignored by JavaScript

The Number Type

The Number data type in JavaScript does exactly what you expect! It is used to represent any numerical values, this includes integers and decimal numbers. As one of our first data types, we'll be interested in what operations we can use with numbers.

When you finish this article, you should be able to:

  • predict the evaluation of arithmetic expressions
  • explain the order of operations for JavaScript's arithmetic operators
  • use the grouping operator, (), to manipulate the order of operations in an expression

All the numbers

JavaScript's Number encompasses numerical values. All of the following values are of number type:

42;
-5;
3.14159;
7.0;

The basic arithmetic operators

For any given data type, we're interested in what operations we can perform with that type. We use the word operator to refer to the symbol that performs a particular operation. For example, the + operator performs the addition operation. Here are the common arithmetic operators in JS:

  • + (addition)
  • - (subtraction)
  • * (multiplication)
  • / (division)
  • % (modulo)

With number values and arithmetic operators in hand, we can evaluate our first expressions:

console.log(2 + 3); // => 5
console.log(42 - 42); // => 0
console.log(-4 * 1.5); // => -6
console.log(25 / 8); // => 3.125

Nothing too groundbreaking about the results above. An expression consists of values and operators. JavaScript will evaluate an expression into a single value.

We can write more complex expressions using multiple operators. However, we'll want to be aware of the general math order of operations. That is, we perform multiplication-division operations first and then addition-subtraction operations. To force a specific order of operation, we can use the grouping operator, ( ), around a part of the expression:

console.log(5 * 3 + 2); // => 17
console.log(2 + 3 * 5); // => 17
console.log((2 + 3) * 5); // => 25

The modulo operation

All of the math operators listed above are the simple operations you use everyday, except for maybe modulo %. Modulo gives us the remainder that results from a division. For example, 10 % 3 is 1 because when we divide 10 by 3, we are left with a remainder of 1. We can read 10 % 3 as "ten modulo three" or "ten mod three."

console.log(10 % 3); // => 1
console.log(14 % 5); // => 4
console.log(20 % 17); // => 3
console.log(18 % 6); // => 0
console.log(7 % 9); // => 7

Modulo is a very useful operation in the realm of computers. We can use it to check the divisibility of numbers, whether numbers are even, whether they are prime, and much, much more. Don't take this seemingly simple operation from granted! We'll provide a ton of practice using these modulo patterns as we move through the course.

In the order of operations, modulo has the the same precedence as multiplication-division. So our complete order of math operations in JS is parentheses, multiplication-division-modulo, addition-subtraction.

// modulo has precedence over addition
console.log(4 + 12 % 5); // => 6
console.log((4 + 12) % 5); // => 1

Remember

  • The Number type is used to represent integer and decimal values
  • The operators +, -, /, * perform the normal math operations of addition, subtraction, division, multiplication respectively
  • a % b returns the remainder when we divide a by b; we call this operation modulo
  • JavaScript follows the usual mathematical order of operations and we can use the () to force precedence

The String Type

This article is about one of JavaScript's primitive data types, String. Strings are what we'll use to represent textual data. This means that strings are useful in representing things like messages, names, poems, and so on. A string is a sequence of characters.

When you finish this article, you should be able to:

  • Write strings using correct syntax
  • Use .length to obtain a count of the numbers of characters that comprise a string
  • Index a string to refer to a single character
  • Concatenate strings together

Writing a valid string

Strings are always wrapped by a pair of single quotation marks (') or by a pair of double quotation marks ("). Between the enclosing quotation marks, we can put any characters! Here are a six examples of strings:

"potato";
"New York";
"azablan@.io";
"Follow the yellow brick road, please!";
"365 days a year";
"";

Above, notice that we are free to mix in any characters into a string. This includes spaces, numerics, punctuation, and other symbols. The sixth string above is the empty string; it contains zero characters!

You are probably wondering why we are allowed to use either single or double quotes when denoting a string - why is this useful? Maybe we want a string that contains quotation marks:

// valid strings
'Shakespeare wrote, "To be or not to be"';
"That's a great string";
// invalid string
'That's a bad string'

If we want to use a single quote as a character of a string, we simply need to enclose the string in double quotes, and vice versa.

Calculating length

Since a single string can contain any number of characters, we may find it useful to count the number of characters in a string using .length:

console.log("ramen".length); // => 5
console.log("go home!".length); // => 8
console.log("".length); // => 0

Indexing a string

Strings consist of multiple characters. These characters are numbered by indices starting at 0. So in the string 'bootcamp', 'b' is at index 0, 'o' is at index 1, 'o' is at index 2, 't' is at index 3, and so on. We can look at particular characters of a string by using [] and specifying an index:

console.log("bootcamp"[0]); // => 'b'
console.log("bootcamp"[1]); // => 'o'
console.log("bootcamp"[2]); // => 'o'
console.log("bootcamp"[3]); // => 't'
console.log("bootcamp"[7]); // => 'p'
console.log("bootcamp"[10]); // => undefined
console.log("bootcamp"[-3]); // => undefined

In general, when we index a string using the expression string[i], we get back the single character at position i. Looking at the last two examples above, if we use an invalid index with a string, the value returned is undefined. This makes since because there is no character at the given position! It's also worth mentioning that an index should always be a number.

The classic "off by one" error

Bear in mind that indices begin at 0 and not 1! Forgetting this nuance can lead to incorrect code for both new and experienced programmers alike. Let's hone in on an important distinction: the index of the last character of a string is always one less than it's length.

console.log("cat".length); // => 3
console.log("cat"[3]); // => undefined
console.log("cat"[2]); // => 't'

In other words, although the length of 'cat' is 3, the index of the last character ('t') is 2.

Using indexOf

We can also calculate the index of a given character within a string by using indexOf:

console.log("bagel".indexOf("b")); // => 0
console.log("bagel".indexOf("a")); // => 1
console.log("bagel".indexOf("l")); // => 4
console.log("bagel".indexOf("z")); // => -1

If we attempt to search for a character that is not present in a string, indexOf will return -1. This makes sense because we know that -1 is not a valid string index. The smallest index possible is 0!

If we search for a character that appears more than once in a string, indexOf will return the index of the first occurance of that character.

We can also use indexOf to search for a substring of characters. Under this circumstance, indexOf will return the index where the substring begins in the main string:

console.log("door hinge".indexOf("oor")); // => 1
console.log("door hinge".indexOf("hi")); // => 5
console.log("door hinge".indexOf("hint")); // => -1

Concatenation

Concatenation is just a fancy word for joining strings together into a single string. To concatenate strings, we use the + operator:

console.log("hello" + "world"); // => 'helloworld'
console.log("goodbye" + " " + "moon"); // => 'goodbye moon'

Remember

  • a String is a data type that contains multiple characters enclosed in quotation marks
  • string.length returns the number of characters in the string
  • each character of a string is associated with a number index; the first character of a string is at index 0
  • we can use string.indexOf(char) to obtain the index of char within string; if char is not found, then -1 is returned
  • we can use + to concatenate multiple strings, combining them into a single string

The Boolean Type

The Boolean data type is perhaps the simplest type since there are only two possible values, true and false. However, we'll find booleans very useful because they will act as components of later concepts. As programmers, we'll use booleans to describe the validity of statements. In an abstract sense, "Today is Monday" and "one plus one equals ten" are examples of statements with boolean values. That is, they are either true or false.

When you finish this article, you should be able to:

  • predict the evaluation of expressions that use the boolean operations of !, ||, and &&
  • explain DeMorgan's law

Logical Operators

In the long run, we'll be using booleans to establish logic in our code. For this reason, the boolean operators can also be referred to as the logical operators. There are only three such operators:

  • ! (not)
  • && (and)
  • || (or)

Logical NOT

The not (!) operator will reverse a boolean value:

console.log(!true); // => false
console.log(!false); // => true
console.log(!!false); // => false

It's worth mentioning that ! is a unary operator. This means that the not operation is applied to a single value. This is in contrast to a binary operator such as multiplication, which is applied between two values. It does not make sense to ! two values together.

Logical AND

The and (&&) operator will take two boolean values and will only evaluate to true when both input values are true. Otherwise, it will return false:

console.log(false && false); // => false
console.log(false && true); // => false
console.log(true && false); // => false
console.log(true && true); // => true

Logical OR

The or (||) operator will take two boolean values and will only evaluate to false when both input values are false. Otherwise, it will return true:

console.log(false || false); // => false
console.log(false || true); // => true
console.log(true || false); // => true
console.log(true || true); // => true

Logical order of operations

We can write boolean expressions that consist of multiple logical operations, but we should be aware of the order of operations. JavaScript will evaluate ! then && then ||.

console.log(true || true && false);    // => true
console.log(false && !(false || true)); // => false

In general, A || B && C is equivalent to A || (B && C) where A, B, C are booleans.

De Morgan's Law

A common mistake in boolean logic is to incorrectly distribute ! across parentheses. Say we had boolean values of A, B. Here is something to remember:

  • !(A || B) is equivalent to !A && !B
  • !(A && B) is equivalent to !A || !B

In other words, to correctly distribute ! across parentheses, we must also flip the operation within parentheses. Beware that:

  • !(A || B) is not equivalent to !A || !B
  • !(A && B) is not equivalent to !A && !B

We call this property De Morgan's Law. Shout out to Augustus De Morgan of Great Britain.

Remember

  • !, &&, || are the boolean operators that we can use to establish logic in our code
  • De Morgan's Law should be used to distribute ! against parentheses

These are just the basics of the type. We'll be seeing more booleans in the upcoming section, so stay tuned for that!


Comparison Operators

In our previous introduction to the boolean data type, we described booleans as way to represent the validity of an expression. We'll continue this conversation by exploring comparison operators. As you learn about these operators, bear in mind that all comparisons will result in a boolean, true or false.

When you finish this article, you should be able to:

  • Predict the result of expressions that utilize the operators >, <, >= <=, ===, and !==
  • Explain the difference between the equality operators == and ===

The relative comparators

  • > (greater than)
  • < (less than)
  • >= (greater than or equal to)
  • <= (less than or equal to)
  • === (equal to)
  • !== (not equal to)

Using these operators is pretty straightforward. Here are a few examples:

console.log(10 > 5); // => true
console.log(10 < 5); // => false
console.log(1 < 7); // => true
console.log(7 <= 7); // => true
console.log(5 === 6); // => false
console.log(5 !== 6); // => true
console.log("a" !== "A"); // => true
console.log(false === false); // => true

Notice that a comparison expression always evaluate to a boolean value (true or false). Comparison operators like === are a useful to compare strings, booleans, etc. not just numbers.

Did you know? 'a' < 'b' is valid JS code? When you relatively compare strings using > or < you will be comparing them lexicographically. Lexicographically is fancy shmancy talk for "dictionary" order! A "lesser" string is one that would appear earlier in the dictionary:

console.log("a" < "b"); // => true
console.log("apple" < "abacus"); // => false
console.log("app" < "apple"); // => true
console.log("zoo" > "mississippi"); // => true

Gotcha capitilized letters are considered lexicographically less than lower case letters. i.e "A" < "z" // => true.

=== vs ==

In JavaScript there are two equality operators triple-equals (===) and double-equals (==). The operators differ in how they compare across differing types. Triple-equals performs the strict equality, meaning it will only return true if the types are the same. Double-equals performs the loose equality, meaning it can return true even if the values are of different type. Double-equals may coerce a value into another type for the comparison, and this behavior is hard to predict:

console.log(5 === "5"); // false
console.log(5 == "5"); // true
console.log(0 === false); // false
console.log(0 == false); //true

Whoa! Surprised by these results? It can be hard to predict how == behaves, so we will avoid using it in this course and as a best practice. Stick to using === because it respects data types.

Remember

  • >, <, >=,<=, ===, and !== can be used to compare values
  • we prefer to use === to check for equality because it takes the type into account.

Basic Variables

Variables are used to store information to be referenced and manipulated in a computer program. They also provide a way of labeling data with a descriptive name, so our programs can be understood more clearly by programmers. It is helpful to think of variables as containers that hold information. Their sole purpose is to label and store data in computer memory. This data can then be used and even changed throughout the lifetime of your program.

When you finish this reading, you should be able to:

  • declare variables using the let keyword
  • assign values to variables using the assignment operator (=)
  • use the shortcuts +=, -=, ++, -- to reassign variables
  • identify undefined as the default value for unassigned variables

Initializing a variable

To initialize a variable in JavaScript we'll need two new pieces of syntax: let and =. We can give the variable any name that we wish and assign it a value. Once we initialize a variable, the variable will evaluate to the value assigned:

let bootcamp = "";
console.log(bootcamp); // ''

let birthYear = 2012;
console.log(birthYear); // 2012

Did you know? JavaScript variables names can contain any alphanumeric characters, underscore (_), or dollar sign ($). However, they cannot begin with a number.

Above are examples of how you'll create variables most of the time, so we'll grow very familiar with the syntax. As a best practice, we should name our variables in a way that is descriptive and concise.

The variable initializations above really consist of two steps: declaration with let and assignment with =. Let's break these two steps down.

Declaring a variable

In JavaScript, in order to use a variable, we must declare it. Variable declaration is the act of introducing the variable to the environment.

To declare a variable, use the let keyword, followed by a space and then the name of the variable.

let bootcamp;
console.log(bootcamp); // undefined

Once a variable is declared, it will contain undefined as it's value. undefined is a common default value in JavaScript, we'll see it come up in a few different places. You can think of undefined as showing that the variable is empty.

Assigning a variable

Once a variable has been declared, we can assign it a value using single-equals = :

let bootcamp;
console.log(bootcamp); // undefined
bootcamp = "";
console.log(bootcamp); // ''

Manipulating variables

To change the value of a variable, we need to reassign it to a new value with = :

let num = 42;
console.log(num + 8); // => 50
console.log(num); // => 42

num = num + 10;
console.log(num); // => 52

In the code above, num + 8 will evaluate to 50, but it will not change the num variable to 50. If we want to change the num variable, we must reassign to it.

Assignment Shorthand

Changing the value of a number variable is something fairly common in the programming world. Luckily there is some shorthand operators we can use:

let number = 0;
number += 10; // equivalent to number = number + 10
number -= 2; // equivalent to number = number - 2
number /= 4; // equivalent to number = number / 4
number *= 7; // equivalent to number = number * 7
console.log(number); // 14

We also have other shorthand to add or subtract exactly 1 from a variable, the increment (++) and decrement (--) operators:

let year = 3004;
year++;
console.log(year); // 3005
year--;
console.log(year); // 3004

NaN

Now that we have the ability to perform arithmetic with variables, let's take a look at a common programming mistake, getting a result of NaN (not a number):

let num;
console.log(num + 3); // NaN

The above code gives NaN because the unassigned num variable contains undefined; adding 3 to undefined results in NaN. In general, any nonsensical arithmetic will result in NaN. Math operations involving undefined is perhaps the most common mistake:

console.log(undefined + 3); // NaN
console.log("fish" * 2); // NaN

Remember

  • variables are declared with let and will contain the value undefined by default
  • we can use single-equals = to assign variables
  • changing a variable requires a reassignment, for which there are many shortcuts for (+=, -=, etc.)

Introduction to Functions

We hope you are ready - because you are on the brink of one of the most fun parts of writing JavaScript: writing functions. A function is a procedure of code that will run when called. We only "write" a function once (function declaration), but we can "use" it as many times as we please (function calls). Functions are the fundamental building blocks of JavaScript and mastering them is a big step on the road to JavaScript mastery.

When you finish this reading, you should be able to:

  1. Describe what a function in JavaScript is.
  2. Demonstrate how to invoke a function.
  3. Write a function using function declaration.
  4. Use the return keyword to return a value from a function.

Writing Functions

A function is a set procedure of code that will run when called. Functions really start to make sense when put in the perspective of solving problems. So for example say you want to find the average of two given numbers. Meaning we want to take two numbers, add them together then divide by 2:

> (5 + 5) / 2
5

> (15 + 3) / 2
9

> (7 + 2) / 2
4.5

Writing out the same code again and again gets tedious fast. What you can do instead is write a new function.

Function Declaration

A function definition consists of the function keyword, followed by three things:

  1. The name of the function.
  2. A list of parameters to the function, enclosed in parentheses, ().
  3. The code to be run when this function is run, enclosed in curly brackets,{ }.

So for our above example of averaging two numbers we could write a function that would do that for us! We would write something like the following:

// 1. average is the name of the function
// 2. number1 & number2 are the parameters being passed in
function average(number1, number2) {
  // 3. this is the code run every time this function is used
  return (number1 + number2) / 2;
}

First thing to notice for the above average function is that we didn't use any real numbers. You always want to write functions to accept as wide a range of data as possible. Utilizing the incoming parameters to a function is one of the keys to making functions flexible.

In the case of the average function, we want to use it to calculate the average of any two numbers. number1 and number2 are the parameters for the average function. In other words, the average function expects to be given two numbers, number1 and number2. We'll be talking a lot more about parameters later - but for now know that when you define a function with parameters you are declaring those parameters as usable variables within that function.

The beauty of a function is that if we define it in a clever way, it will work on a whole slew of data! For example, we want average to work on any two numbers, whether or not they are whole numbers, decimal, negative, etc.

Invoking or "calling" a function

Now that we've written a function how do we actually use it? Once defined a function can be invoked or "called" as many times as we please.

Order of code

Let's step away from average for a bit to see how a simple function call works. Say we run JavaScript code that looks like this:

console.log("First!");

console.log("Second!");

Running this code will return exactly as we expect. We will see First! printed out, followed by Second!. In other words, JavaScript will evaluate your code left-to-right and top-to-bottom. Very intuitive! It's exactly how you are reading these notes right now.

However, when JavaScript sees a function definition, JavaScript will not evaluate the code inside of the definition. It will only "remember" the code so we can execute it later. The code below only prints First! followed by Fourth!:

console.log("First!");

function callMe() {
  console.log("Second!");
  console.log("Third!");
}

console.log("Fourth");

// when run this code is ran it will print out:
// "First!"
// "Fourth"

To actually get the code within callMe to evaluate, we must call it by using callMe(). The code below will now print out in order:

function callMe() {
  console.log("Second!");
  console.log("Third!");
}

console.log("First!");
// we call the function by adding ending parenthesis
callMe();
console.log("Fourth!");

// when run this code is ran it will print out:
// "First!"
// "Second!"
// "Third!"
// "Fourth"

Let's say JavaScript is running the file above. Here are the steps it would take, starting from the tippy top of the code:

  1. JS sees a definition for callMe. It will remember this definition in case we call the function later. It will not evaluate the code inside the function yet.
  2. JS prints out First!
  3. JS sees that we are calling callMe(). At this point it will look at the prior callMe definition and run the code inside. It is as if we are "jumping" to inside the function definition. This means it will print Second! followed by Third!
  4. JS sees there is no more code to be run inside of callMe, so it "jumps" back to where we originally called callMe()
  5. JS will continue evaluating in order and print Fourth!

An average example

So a declared function is "saved for later use", and will be executed later, when it is called, also known as being invoked. So thinking back to our average function we can declare the function and then invoke it.

When we specify what data to use for a function call, we refer to that process passing arguments to the function.

// this is a function definition
function average(number1, number2) {
  return (number1 + number2) / 2;
}

// this is a function call with the arguments being 15 & 3
> average(15, 3)
9

// this is a function call with the arguments being 5 & 5
> average(10, 5)
7.5

When we call the function average(15, 3), we run the code inside the definition for average. That is, we plug in the parameters with real numbers (number1 becomes 10 and number2 becomes 16). Think of number1 and number2 as variables that contain the values we pass in when we called the function. Then we proceed by running the code inside the function. The parameter names number1 and number2 used through the body of the function and behave like variables.

Returning a value

Now that we know how functions are declared and invoked let's talk about the inside of the function. We'll start with a statement: Every function in JavaScript returns undefined unless otherwise specified.

Now what does that mean? We'll start with a simple example:

function sayNumber(number) {
  console.log(number);
}

> sayNumber(1); // prints 1
1
undefined

So what happened there? Let's do a quick step by step:

  1. We declared the sayNumber function
  2. sayNumber was called handing in the argument of 1
  3. The number parameter is printed to the console
  4. Then the function ends without encountering a return statement. Since nothing was specifically returned then the function returned the default value for a function which is undefined.

Now let's change our above example to use the keyword return to return a value:

function sayNumber(number) {
  console.log(number);
  return true;
}

> sayNumber(1);
1 // sayNumber still prints 1
true // but now sayNumber returns as true

Let's go back to our previous average function and talk about the return we used there:

function average(number1, number2) {
  return (number1 + number2) / 2;
}

// the function call for average(10, 16) will return 13
// so the result variable will be set to 13
let result = average(10, 16);

// if we want to check what a function returns we can do this:
console.log(result); // prints `13`

// we could alternatively do this:
console.log(average(10, 16));

When we call a function, we jump to the function definition and run the code inside. When we hit a return statement, we immediately exit the function, jump back to where we called the function, and evaluate the function call to the value it returned.

Every function call evaluates to it's return value! In other words, the expression average(10, 16) evaluates to 13 just like how the expression 1 + 1 evaluates to 2.

Another important rule of the return statement is that it stops function execution immediately. This means that any code after a return will not be executed!

function average(number1, number2) {
  let sum = number1 + number2;
  return sum;
  // anything under the first return will not be executed
  console.log("this will not run")
  return false;
}

 // when the first return is encountered the entire function will return a value
> average(2, 7);
9

So the three things to remember about return statements is:

  1. Every function call evaluates to it's return value.
  2. Every function in JavaScript returns undefined unless a return is specified
  3. Once a return statement is encountered the function will immediately stop and return the value, ignoring any code below the return statement.

The importance of naming

A quick but very important side note about good naming. Take this to heart right now: Good names are important. Do yourself, and every other programmer reading your code, a favor by always using significant function and variable names.

For example, x is a very non-descriptive name for a variable or function. As we tackle more complicated problems and our code grows to be more complex, we are likely to forget what badly named variables originally stood for and what their purpose was. Non-descriptive names make our code error-prone. Great code reads like English and almost explains itself. As programmers, our goal is to write code that is not only "correct", but also elegant, readable, and maintainable! Hold yourself to this high standard.

As far as syntax goes in JavaScript we always name our functions and variables camelCase for multiple words. (Ex: tipCalculator, currentNumber, puppyPartyFinder). Other languages use other conventions so it's best to pick up the standard for your chosen language and stick with it.

Review

By writing a function we can reuse code over and over again to solve similar problems with different input data (arguments). This will make your life easier and allow you to start working on more complex problems.

This reading covered:

  • How to define and invoke a function in JavaScript.
  • How to use the return keyword to return a value from a function.
  • Writing readable JavaScript code by using significant names and following camelCase conventions for multiple word variables and functions

Parameters and Arguments

When talking about functions one of the first things we mentioned was the word parameters. In this reading we will be covering what exactly a parameter is - as well as the differentiation between parameters and arguments.

When you finish this reading, you should be able to:

  1. Identify the difference between parameters and arguments.
  2. Write a function that utilizes declared parameters.
  3. Invoking a function with passed in arguments.

The difference between Parameters and Arguments

Let's start off by talking about the difference between arguments and parameters and how to identify which is which.

  1. Parameters are comma separated variables specified as part of a function's declaration.
  2. Arguments are values passed to the function when it is invoked.

So by defining parameters when we declare our function we are effectively setting accessible variables within the function:

function add(firstParameter, secondParameter) {
  console.log(firstParameter + secondParameter);
}

// the add function declares two parameters
> add(1, 2); //=> 3

In the above example we declared our parameters when we declared our function. Now arguments work slightly differently - when the function is invoked we are passing in arguments. So in the above example when we invoked add(1, 2) the (1,2) were the arguments being passed in. So when a function is invoked the value of the declared parameters is assigned to the passed in arguments.

You can think of it parameters and arguments like a recipe. A recipe is a list of ingredients (parameters) and list of steps (the code to be run). When someone cooks the recipe (invokes the function) they add the ingredients they actually have(arguments). The result of cooking the recipe is the delicious return value!

Extra arguments

In JavaScript a function will not throw an error if the number of arguments passed during a function invocation is different than the number of parameters listed during function declaration. This is very important to know!

Let's use the above function to demonstrate:

function add(firstParameter, secondParameter) {
  console.log(firstParameter + secondParameter);
}

// this will ignore the 17 & 14
// the first two arguments passed in will be assigned to the first two parameters
> add(1, 2, 17, 14); //=> 3

Notice in the above example we passed in 4 arguments (1, 2, 17, 14) to add. Since the function was only looking for two parameters that is all it uses.

Not enough arguments

Now what happens if we pass in less arguments then needed?

function add(firstParameter, secondParameter) {
  console.log(firstParameter + secondParameter);
}

> add(5); //=> NaN

Whoa what happened there? Let's do a play-by-play:

  1. firstParameter was set to equal the first passed in argument which in the above case is 5.
  2. Since there is no second argument then secondParameter is declared as a variable but is set to the default value of undefined.
  3. The function then tries to add 5 to undefined which is definitely not a number! So we get NaN (which means Not A Number) printed to the console.

As you write more functions you'll grow very comfortable using both arguments and parameters to accomplish your function's goal.

Review

  • Parameters are variables defined as a part of a function's declaration.
  • Arguments are values passed to the function when it is invoked.
  • JavaScript functions can intake a different number of arguments than the number of parameters listed during function declaration.

WEEK-01 DAY-2
Control Flow {ignore=true}


Control Flow and Array Learning Objectives

Below is a complete list of the terminal learning objectives for this lesson. When you complete this lesson, you should be able to perform each of the following objectives. These objectives capture how you may be evaluated on the assessment for this lesson.

  1. Define a function that accepts a sentence string and two words as args. The function should return a boolean indicating if the sentence includes either word.

  2. Identify a pair of mutually exclusive conditions

  3. Given a for loop, translate it into a while loop, and vice-versa

  4. Write a function that iterates through a provided string argument

  5. Given a description of pig latin, write a function that takes in a string argument and utilizes String#slice to translate the string into pig latin.

  6. Write a function that takes in an array of words and a string as arguments and returns a boolean indicating whether the string is located inside of the array. The function must use Array#indexOf.

  7. Define that an array literal is an ordered list of values defined by using bracket and individual values are read by indexing.

  8. Prevent code that can throw an exception from causing the program to crash. the terminal learning objectives for this lesson. When you complete this lesson, you should be able to perform each of the following objectives. These objectives capture how you may be evaluated on the assessment for this lesson.

  9. Define a function that accepts a sentence string and two words as args. The function should return a boolean indicating if the sentence includes either word.

  10. Identify a pair of mutually exclusive conditions

  11. Given a for loop, translate it into a while loop, and vice-versa

  12. Write a function that iterates through a provided string argument

  13. Given a description of pig latin, write a function that takes in a string argument and utilizes String#slice to translate the string into pig latin.

  14. Write a function that takes in an array of words and a string as arguments and returns a boolean indicating whether the string is located inside of the array. The function must use Array#indexOf.

  15. Define that an array literal is an ordered list of values defined by using bracket and individual values are read by indexing.

  16. Prevent code that can throw an exception from causing the program to crash.


Control Flow - Conditional Statements

So far the code you've written has been pretty direct in it's intent. You can define functions and variables but, so far the functions you've created haven't been able to do that much for you yet. It's time to start writing functions that can do things conditionally by utilizing control flow.

In simple terms - control flow is the order in which instructions are executed within a program. One modifies control flow using control structures, expressions that alter the control flow based on given parameters. The control structures within JavaScript allow the program flow to change within a unit of code or a function.

This reading will be covering one of the two main control structures you will use time and time again - Conditional statements. Conditional statements are used to perform different actions based on different conditions.

When you finish this reading, you should be able to:

  • Write if, else if, if...else conditional statements.
  • Know that conditional statements can have only one if and one else statement.
  • Identify that conditional statements can be nested.

A Quick Word on Syntax

Before we get started we'll quickly go over the terms we'll be using to represent syntax.

  1. [ ] are square brackets
  2. { } are curly braces
  3. ( ) are parentheses

Writing Conditional Statements

Conditional Statements are the second fundamental control structure for writing JavaScript and are pretty straight forward. The simplest conditional statement is the if statement. An if statement has two parts, the test expression (the code that immediately follows the if which goes in parentheses), and the then expression (this code belongs in braces after the if expression). The then expression will only run when the if expression is truthy.

Here is an example of a simple if statement:

// this is the test expression
if (3 === 3) {
  // this is the then expression
  // this code will run if the above statement is true
  console.log("this is a three!");
}

The if statement above allows you to specify what should happen if your particular expression evaluates to true. You can chain additional test expressions onto this if statement by using a else if statement.

The syntax for else if is very similar as an if statement:

function mathFun() {
  let x = 2 + 3;

  if (x === 3) {
    console.log("we have a 3");
  } else if (x === 4) {
    // this code will run if the above statement is true
    console.log("we have a 4");
  } else if (x === 5) {
    // this code will run if the above statement is true
    console.log("we have a 5");
  }
};

mathFun(); // => "we have a 5"

The else if and if statements do not, however, provide the option to specify something else that should happen in the event that all of the above expressions evaluate to be falsey. The if...else statement reads just like English. The JS interpreter will execute the else statement if all the above conditions given are falsey. See below for an example:

function mathFun() {
  let x = 19;
  if (x === 3) {
    console.log("we have a 3");
  } else if (x === 4) {
    console.log("we have a 4");
  } else {
    console.log("I will return if everything above me is falsey!");
  }
};

mathFun(); // => "I will return if everything above me is falsey!"

You can chain an arbitrary number of else if statements but there can only be one if statement and one optional else statement. The if introduces the control structure and the else acts as a fail safe to catch everything that didn't meet the above conditions.

Only one then expression is ever executed in an if, if...else, or if...else statement. If one of the test expressions is truthy, then the result of its then expression is the result of the entire conditional statement:

let x = 3;
if (x === 3) {
  console.log("this will run");
} else {
  console.log("this will not run");
}

Additionally, you can nest conditional statements within each other but it will get hard to read pretty quickly and is discouraged:

function mathFun(x) {
  if (x === "math") {
    if (x === "math" && x[0] === "m") {
      if (x[1] === "a") {
        console.log("this got confusing fast");
      } else {
        console.log("that is not math!");
      }
    } else {
      console.log("that is for sure not math!");
    }
  } else {
    console.log("I will return if everything above me is false!");
  }
};

mathFun("math"); // => "this got confusing fast"

Review

  • Conditional statements allow us to control what actions should be taken based on a boolean (truthy or falsey) expression
  • In a chain of then expressions (if...else if...else), only one of the then expressions will be executed.
  • Conditional statements can have only one if and one else statement.
  • Conditional statements can be nested.

Mutually Exclusive Conditions

You have now learned how to write conditional statements. Now we'll talk a little bit more about how to write them using best practices.

When you finish this reading, you should be able to:

  • Identify a pair of mutually exclusive conditions.

When to use if statements

Say you are given the challenge to write a function that that will call another function named bigNumber if the given argument is greater than 100 or call a function named smallNumber if it the given argument is smaller. You could write a function to do that which would look like this:

function numberSeparator(number) {
  if (number < 100) {
    // number is smaller than 100 so we invoke smallNumber
    smallNumber();
  }
  if (number === 100) {
    // number is equal to 100 so we invoke smallNumber
    smallNumber();
  }
  if (number > 100) {
    // number is larger than 100 so we invoke bigNumber
    bigNumber();
  }
}

As you can probably tell the above function uses a lot of code to do a simple task. To be clear the function above would work for our aim - but it repeats itself. There is an age old principal for writing good code named DRY or Don't repeat yourself. As good programmers we always want our code to be clear, concise, and efficient.

A general rule of thumb is that if you are working with a condition that is mutually exclusive, meaning if one condition is true the other condition must be false, then you should use an if/else statement. You can also think of mutually exclusivity like a coin flip - it can be either heads or tails but not both.

Going back to the original problem at hand we can see it makes intuitive sense with the way the challenge is phrased: If the number is larger than 100 then we'll call bigNumber, otherwise we invoke is smallNumber.

So let's rewrite the above function to read a little more clearly:

function numberSeparator(number) {
  if (number > 100) {
    bigNumber();
  } else {
    smallNumber();
  }
}

// this also works
function numberSeparator(number) {
  if (number <= 100) {
    smallNumber();
  } else {
    bigNumber();
  }
}

Look at how much clearer that is! Writing good code is an art - devote yourself to becoming an artist!

Review

  • How to identify a pair of mutually exclusive conditions.
  • DRY - don't repeat yourself!

Control Flow - Looping

A quick reminder before we start - control flow is the order in which instructions are executed within a program. One modifies control flow using control structures, expressions that alter the control flow based on given parameters. This reading will be covering the second of the main control structures you will use time and time again - loops.

When you finish this reading, you should be able to:

  1. Know how to write a while loop and a for loop.
    • Know how to convert a for loop into a while loop
  2. Know that index variables conventionally start at zero.
  3. Explain what an iteration is.

Looping

Imagine you are at a friend's house and your friend has six dogs. Someone left the back gate open and all the dogs go out in the yard and get super muddy. Now your friend wants to clean their dogs but they only have one bathtub! You can't wash all the dogs at once. So the only option is to give the dogs a bath one at a time until they are all clean. When you start 0 dogs are clean and 6 dogs are dirty.

While there are still dirty dogs you still have a job to do. That is your condition - you will stop giving baths once all 6 dogs are clean. So after one bath you you have 1 clean dog and 5 dirty dogs. You've incremented(increased by one) your number of clean dogs. After each bath you check your condition again until you have 6 clean dogs so you know you can stop!

What we've described above is the idea of looping - setting a condition, executing an action, doing something to make sure our condition will be met eventually, and rechecking our condition before executing our next action.

Loops are a fundamental control structure for writing JavaScript. Loops will repeatedly execute a section of code while a condition is true. Loops are simple to write and incredibly powerful! There are many variations of loop but we will be covering the two most fundamental loops now - while loops and for loops.

While Loops

One of the simplest loops in JavaScript is the while loop. As with all loops, the while loop will execute a block of code as long as a specified condition is true. The while loop starts with the keyword while then states a condition in parentheses. The code in the following braces will be run until the above condition is met.

while (condition) {
  // code block to be executed
}

In the following example, the code in the loop will run, over and over again, as long as a variable (index) is less than 10:

let index = 0;

// this is the condition that will be checked every time this loop is run
while (index < 10) {
  console.log("The number is " + index);
  // this is common shorthand for index = index + 1
  index++;
}

The most important thing to remember when writing any loop is to always be working towards your condition. In the example above if we did not increment the index variable by 1 each time the loop ran then we would be stuck with what we call an infinite loop:

let index = 0;

// this is an infinite loop because our condition will never be met
while (index < 10) {
  console.log("The number is " + index);
  // if we do not increase the index then our condition is never met
  // Meaning this will run forever!
}

The above code will run until whatever interpreter you are using crashes.

Important Loop Knowledge

A quick word before we learn about the next loop.

The index is the traditional word for the variable that keeps track of how many times the loop has been run. Don't write loops with indices starting at one; you'll confuse other programmers and yourself. Indices have started at zero for a long time, and for good reason. It's much easier to use loops that start with an index of zero because Array and String indices also start at zero.

let array = [0, 1, 2];
let index = 0;

while (index < array.length) {
  console.log(
    "Both the index and the current array position are " + array[index]
  );
  index++;
}

In the above code we will do one loop for each digit in the Array above. We call each of those loops an "iteration". An iteration is the act of repeating a procedure, hence looping is an iterative technique. Each repetition itself is also called an "iteration." So you can use loops to iterate through Arrays and Strings.

For Loops

A for loop can be broken down into three sections:

  1. The initial expression which will be run once at the beginning of the loop.
  2. The condition which is checked every time the loop is run. If this condition is true the loop will run again. If this condition is false the loop will end.
  3. The loopEnd expression which will be run at the end of the loop before checking the condition again.
for (<initial expression>;<condition>;<loopEnd expression>)

The for loop is usually used with an integer counter:

for (let index = 0; index < 10; index += 1) {
  // the code inside this block will run 10 times
}

While the loopEnd expression is normally used to increase a variable by one per loop iteration, it can contain any statement, such as one that decreasing the counter, or increasing it by 2.

You can use the for loop to iterate through all kinds of things. Check out the example below for how to iterate through a String:

let testString = "testing";

// we can use the testString's length as our condition!
// Since we know the testString's index starts at 0
// and our index starts at 0 we can access each letter:
for (let index = 0; index < testString.length; index += 1) {
  let letter = testString[index];
  console.log(letter);
}

These are the most basic types of loops. If all else fails, you can always fall back on these two loops. All the other loop forms are just more convenient forms of these basic loop styles.

Translating From One Loop to Another

So far we have covered both while and for loops. Once you understand the concept of looping it's easy to translate one loop to another:

// these two do the exact same thing!
function forLoopDoubler (array) {
  // it is convention to shorten index to just i in most cases
  for (let i = 0; i < array.length; i++) {
    array[i] = array[i] * 2;
  }
  return array;
};

function forLoopDoubler (array) {
  let i = 0;
  while (i < array.length) {
    array[i] = array[i] * 2;
    i++;
  }
  return array;
};

forLoopDoubler([1, 2, 3]); // => [2,4,6]
whileLoopDoubler([1, 2, 3]); //=> [2,4,6]

Review

  • We can use a for or while loop to repeat a block of code repeatedly.
  • While the loop condition is true, we will execute another iteration of the loop.
  • When the loop condition is false, we will exit the loop.

The Array Type

This reading will be about one of JavaScript's global objects, the Array type. JavaScript arrays are used to store multiple values all within a single structure, much like a creating a list. Arrays can hold strings, integers and even other arrays! Arrays are incredibly useful for holding a bunch of different information all in one place.

When you finish this reading, you should be able to:

  • Write arrays using correct syntax
  • Identify that an array is an ordered list of values defined by using brackets
  • Use .length to obtain a count of the numbers of elements that comprise an array
  • Index an array to refer to a single value
  • Concatenate multiple arrays together

Using arrays

While coding you will find that you often find yourself needing to refer to a bunch of data at once. For instance, what if you wanted to refer to the entire English alphabet. Sure, you could create a bunch variables for each letter in the alphabet:

let a = "a";
let b = "b";
let c = "c";
let d = "d";
// and so on for way too long...

However this becomes cumbersome and unmanageable quickly. An Array is a data structure that solves this problem. Arrays are always wrapped in square brackets, [], and store their comma separated values in sequential order. Arrays in JavaScript are also very flexible: we can put elements into an array, replace elements in an array, and remove elements from the array.

So going back to our first example of containing the alphabet:

let alphabet = [
  "a", "b", "c", "d", "e", "f",
  "g", "h", "i", "j", "k", "l",
  "m", "n", "o", "p", "q", "r",
  "s", "t", "u", "v", "w", "x",
  "y", "z"
];

Indexing arrays

Calculating the length of an array

Since an array can container any number of values you will find it useful to count the number of values available to you using .length:

console.log([4, 7, 9].length); // => 3
console.log([1, 2].length); // => 2
console.log([].length); // => 0

Properly indexing an array

Arrays consist of multiple values all stored in sequential order. These value are numbered by indices starting at 0 (just like indexing a string!). So given the below example:

let numbersAndLetters = ["b", "z", 17, "cat"];

In the above numbersAndLetters array if we access numbersAndLetters at the index of 0 we get back the value of "b". If we access numbersAndLetters at the index of 1 we get "z", at the index of 3 we get 17, etc. We can specify which value we'd like to access in an array by using square brackets,[], and specifying an index:

console.log(numbersAndLetters[0]); // => "b"
console.log(numbersAndLetters[1]); // => "z"
console.log(numbersAndLetters[2]); // => 17
console.log(numbersAndLetters[3]); // => "cat"

Notice that even though the index at numbersAndLetters[3] has the value of a string with multiple characters ("cat") we return the entire value listed at that index.

Reminder: Arrays always start at the index of 0, not 1. This is the convention in programming. Additionally, indices should always be a number.

We can access a value in an array directly by providing an index for the value we'd like to access in that array (array[index]). See below for an example:

console.log(["a", "b", "c"][0]); // => "a"
console.log(["a", "b", "c"][1]); // => "b"
console.log(["a", "b", "c"][2]); // => "c"
console.log(["a", "b", "c"][3]); // => `undefined`

As we see in the code above, if we try to access an element at an index that is not inside the array, we get back undefined. This makes sense because there is no value at that given position!

The classic "off by one" error

Arrays are similar to strings in that both of their indices start at 0 instead of 1. Forgetting this fact can lead to some pretty confusing situations. Let's focus on an important distinction: the index of the last value of an array is always one less than its length.

console.log([4, 7, 9].length); // => 3
console.log([4, 7, 9][3]); // => undefined
console.log([4, 7, 9][2]); // => 9

In other words, although the length of [4, 7, 9] is 3, the index of the last value (9) is 2. A good rule of thumb of accessing the last index of an array is to find the length and then subtract one:

let testArray = [4, 7, 9];
let finalIndex = testArray.length - 1; // => (3 - 1) = 2
console.log(testArray[finalIndex]); // => 9

Working with arrays

Containing data in arrays

By packaging groups of related data into a single array, we gain the added benefit of being able to refer to that data as a single collection. Arrays don't have to just hold single characters- they are capable of holding entire strings, numbers, and even other arrays!

let wackyArray = [2, 17, "apple", "cat", ["apple"]];

console.log(wackyArray[0]); // => 2
console.log(wackyArray[1]); // => 17
console.log(wackyArray[3]); // => "cat"
console.log(wackyArray[4]); // => ["apple"]

Just think of all the possibilities of what you can store in a single array! However, just because you can doesn't mean you should. In practice we will almost always be storing similar kinds of data, that are coming from a common source (i.e. items in a shopping list, ID numbers, tasks on a todo list).

Using indexOf with arrays

We can also calculate the index of a given value within an array by using indexOf:

console.log([1, 3, 5, "apple", "jet"].indexOf(3)); // => 1
console.log([1, 3, 5, "apple", "jet"].indexOf(5)); // => 2
console.log([1, 3, 5, "apple", "jet"].indexOf("jet")); // => 4

// this won't be found in the array
console.log([1, 3, 5, "apple", "jet"].indexOf("potato")); // => -1

If we attempt to search for a value that is not present in an array, indexOf will return -1. This makes sense because we know that -1 is not a valid array index. The smallest index possible is 0!

Concatenation with arrays

As a reminder, concatenation is just a fancy word for joining things together into a single collection. Now, this is where arrays will differ from strings. The + operator only exists for numbers and strings. If you try to use the + on an array it will try to help you out by converting your arrays into strings.

console.log([1, 2, 3] + [4, 5, 6]); // => 1,2,34,5,6

JavaScript was just trying to help! However that is probably not what you meant to do. Good thing JavaScript has a seperate method for putting two array together. To concatenate arrays, we can use the aptly named .concat method:

console.log([1, 2, 3].concat([4, 5, 6])); // => [1, 2, 3, 4, 5, 6]

Remember

  • An Array is a data type that contains a list of in order values surrounded in square brackets [].
  • array.length returns the number of values in the array.
  • Each value of an array is associated with a number index; the first value of an array is at the index of 0.
  • We can use array.indexOf(value) to obtain the index of value within array; if value is not found, then -1 is returned.
  • We can use .concat to concatenate multiple arrays, combining them into a single array.

WEEK-01 DAY-3
Intermediate Functions {ignore=true}


Intermediate Functions Learning Objectives

Below is a complete list of the terminal learning objectives across all "Intermediate Function" lessons. When you complete these lessons, you should be able to perform each of the following objectives. These objectives capture how you may be evaluated on the assessment for these lessons.

  1. Identify that strings are immutable and arrays are mutable

  2. Define a function using both function declaration and function expression syntax

  3. Utilize Array#push, #pop, #shift, #unshift to mutate an array

  4. List the arguments that can be used with Array#splice

  5. Write a function that sums up elements of an array, given an array of numbers as an argument

  6. Utilize Array#forEach, #map, #filter, #reduce in a function

  7. Define a function that takes in an array of numbers and returns a new array containing only the primes

  8. Define a function that takes in a 2D array of numbers and returns the total sum of all elements in the array

  9. Define a function that takes in an array of elements and returns a 2d array where the subarrays represent unique pairs of elements

  10. Define a function that takes in an array of numbers as an argument and returns the smallest value in the array; if the array is empty return null the terminal learning objectives across all "Intermediate Function" lessons. When you complete these lessons, you should be able to perform each of the following objectives. These objectives capture how you may be evaluated on the assessment for these lessons.

  11. Identify that strings are immutable and arrays are mutable

  12. Define a function using both function declaration and function expression syntax

  13. Utilize Array#push, #pop, #shift, #unshift to mutate an array

  14. List the arguments that can be used with Array#splice

  15. Write a function that sums up elements of an array, given an array of numbers as an argument

  16. Utilize Array#forEach, #map, #filter, #reduce in a function

  17. Define a function that takes in an array of numbers and returns a new array containing only the primes

  18. Define a function that takes in a 2D array of numbers and returns the total sum of all elements in the array

  19. Define a function that takes in an array of elements and returns a 2d array where the subarrays represent unique pairs of elements

  20. Define a function that takes in an array of numbers as an argument and returns the smallest value in the array; if the array is empty return null


Function Expressions

You may have noticed that we've been writing many functions so far in the course! We will continue to do so since functions are the building blocks of the eventual applications that we will build. That being said, let's begin to broaden the way we think about functions. In particular, we'll want think of functions as expressions that we can store in variables - just like our classic data types of number, string, boolean, array, and object!

When you finish this article, you should be able to:

  • identify functions as first-class objects in JavaScript
  • define a function using function expression syntax

Functions as first-class objects

JavaScript is well known for being a programming language that treats functions as "first-class objects". This fancy talk means that you can treat a function as a "normal" value by storing it in a variable. We'll leverage this key concept in very clever ways later in the course. For now, let's begin with a simple example that shows the "first-class object" nature of functions:

let calculateAverage = function(a, b) {
  return (a + b) / 2;
};

console.log(calculateAverage(10, 20)); // 15

In the code snippet above, we define the calculateAverage by assigning a variable to contain the function's definition. By doing this, the variable's name is effectively the function's name. So to call the function, we simply refer to the variable name. Note that we do not write the function's name after the function keyword, where we normally would. We will refer to this new way of defining functions as function expression syntax and the classic way of defining functions as function declaration syntax. In general, we can define functions using either syntax:

// function declaration syntax
function myFunctionName(arg1, arg2) {}

// function expression syntax
let myFunctionName = function(arg1, arg2) {};

In the coming sections, we'll highlight moments when we'll prefer one syntax over the other. For now, get acquainted with the new syntax as it is something you'll be seeing a lot of as a programmer!

A peek under the hood

Perhaps you're finding it tough to understand what it means for a variable to contain a function - it is indeed a very abstract idea for new programmers. Let's draw a comparison. We know that when we assign an expression to variable, the expression first evaluates to a single value, which we then store in the variable name:

let myNum = 4 + 4;
console.log(myNum); // prints 8
console.log(myNum * 3); // prints 24

In the same way we can treat a function definition as an expression that evaluates!

let myFunc = function() {
  console.log("I'm a function");
};

console.log(myFunc); // prints [Function: myFunc]
myFunc(); // prints "I'm a function"

Looking at the snippet immediately above, you'll notice that when we print the myFunc variable directly, without calling the function with parentheses, JavaScript simply says the variable contains a function named myFunc ([Function: myFunc]). You can truly imagine a function as a value that we can store and use as we please.

The term anonymous function may also be used to describe a function expression before it is assigned to any variable. Following the example above, we'll use the word anonymous function to describe the function expression before the assignment to the myFunc variable is complete. Once the assignment is complete, it would be silly to refer to myFunc as an anonymous function because an anonymous function has no name.

Remember

  • functions can be stored in variables; just like any other values in JavaScript!

Two-Dimensional Arrays (2D Arrays)

Time to broaden our understanding of arrays! We've already explore the fundamentals of arrays. Mainly, we can store any type of data we please as elements of an array and even mix types together. However, what happens if we store an array as an element of an array?

When you finish this article, you should be able to:

  • index into the inner elements of a 2D array
  • use nested loops to iterate through a 2D array

Multidimensional Arrays

When we store arrays as elements of other arrays, we refer to those structures as multidimensional arrays. If the "depth" of the nested arrays is at exactly 2 (an outer array containing inner arrays), then we'll refer to it as a two-dimensional array:

let twoDimensional = [["a", "b", "c"], ["d", "e"], ["f", "g", "h"]];

console.log(twoDimensional[1]); // [ 'd', 'e' ]
console.log(twoDimensional[1][0]); // 'd'

let subArr = twoDimensional[1];
console.log(subArr[0]); // 'd'

Note that indexing the outer twoDimensional array will return an element like usual, it's just that element happens to be another array. To gain access to the innermost elements, we simply need to apply another set of indexing brackets!

If we style our 2D arrays nicely so that each subarray is on a new line, we can interpret the double indices as [row][column]:

let twoDimensional = [
  ["a", "b", "c"],
  ["d", "e"],
  ["f", "g", "h"]];

// get the element in the 0th row, 2nd col:
console.log(twoDimensional[0][2]); // 'c'

Iterating through 2D Arrays

Since a 2D array is just an array of arrays. We'll need to use a loop within a loop to iterate through a 2D array:

let array = [["a", "b", "c"], ["d", "e"], ["f", "g", "h"]];

for (let i = 0; i < array.length; i++) {
  let subArray = array[i];
  console.log(subArray);

  for (let j = 0; j < subArray.length; j++) {
    console.log(subArray[j]);
  }
}

In the nested loops above, the i index refers to the current "row" and the j index refers to the current "column". It's worth noting that since the inner subArrays have different length, we'll want to specifically reference the length of that subarray in our inner loop condition j < subArray.length. The code above will print:

[ 'a', 'b', 'c' ]
a
b
c
[ 'd', 'e' ]
d
e
[ 'f', 'g', 'h' ]
f
g
h

When is a 2D array practical?

As a preview of things to come let's briefly mention when you'll find a 2D array useful in your future projects. Imagine how'd you represent a "grid":

  • tic-tac-toe (3x3 grid)
  • chess (8x8 grid)
  • sudoku (9x9 grid)
  • excel (a sheet is an arbitrarily sized 2D array)

Remember

  • an array can contain arrays as elements, we call this a 2D arrays
  • to iterate through a 2D array, used nested loops

Mutability in JavaScript

So far in the course we've explored a handful of methods that manipulate data. We'll be growing our arsenal of methods further overtime, so we'll want to gain awareness for exactly how we should expect these methods to manipulate the data we give them. To this end, let's analyze which methods will modify existing data and which methods do not. We refer to this concept as mutability.

When you finish this article, you should be able to:

  • Explain what "mutability" is
  • Correctly label JavaScript data types as immutable or mutable

What is mutability?

At its face value, mutability is a simple concept. You may be familiar with the word mutation, which refers to a alteration (usually in DNA). Something that is mutable can be changed, while something that is immutable is unchanging and permanent. To illustrate this concept, we'll begin with strings and arrays. We've spent some time with these two data types and by now we recognize that the two types share many similarities. Both have indices, length, and even share common methods like slice. However, they differ greatly in their mutability:

let myArr = ["b", "e", "a", "m"];
myArr[0] = "s";
console.log(myArr); // 'seam'

let myStr = "beam";
myStr[0] = "s";
console.log(myStr); // 'beam'

Above we have shown that we can assign a new element to an index of an array, but we cannot assign a new character to an index of a string. In other words, arrays are mutable, but strings are immutable.

An implication of this discovery is that there are some array methods that will modify an existing array but zero methods that will modify an existing string. Methods that manipulate string data typically return a new string and never modify an existing one. A prime example is toUpperCase:

let word = "piñata";
let newWord = word.toUpperCase();
console.log(word); // 'piñata'
console.log(newWord); // 'PIÑATA'

Above, notice that the toUpperCase method returns a capitalized version of the string, but does not change the original string. It's also worth noting that not every array method will mutate. For example, the slice method does not mutate for both strings and arrays. As we learn about methods in the future, we'll be certain to note what mutates and what does not.

Mutable or immutable, that is the question

Now that we have a grasp of mutability, let's take inventory and identify JavaScript's data types as mutable or immutable.

Mutable

  • array
  • object (we'll learn these soon)

Immutable

  • number
  • string
  • boolean

A quick way to remember the above list is to identify that the composite types (the types that can contain multiple values) of array and object are mutable. The remaining "simpler" types of number, string, and boolean are immutable.

The mutability misconception

Maybe you are having a tough time believing what we have just claimed. We don't blame you, you've probably heard the saying that change is the only constant in the universe. Let's debunk a common argument to turn you into a believer. The skeptical programmer may use this as an argument to show that numbers are mutable:

let myNum = 42;
myNum += 8;
console.log(myNum); // 50

Because the myNum variable now contains 50 where it once contained 42, it may seem we have mutated the number, but this is not truly the case. Recall that myNum += 8 is shorthand for myNum = myNum + 8. Since the right hand side of the assignment evaluates first, we are simply taking the new number of 50 and reassigning it to the myNum variable. This reassignment of a variable name is not a mutation of the original number.

Remember

  • data types that can be changed are mutable, those that cannot be changed are immutable
  • arrays and objects are mutable
  • numbers, strings, and booleans are immutable

Array Splice

Time to a learn yet another array method! The Array#splice method deserves its own reading because of how versatile it is. Feel free to use this article as a quick reference; let's jump right in.

When you finish reading this article, you should be able to:

  • list all possible arguments that can be used with the Array#splice method

Notation

For clarity in this article and moving forward in the course, we'll be notating methods with # to clarify how they should be called. For example, Array#splice refers to the method that should be called on an array, arr.splice() where arr is some array variable. Likewise String#toUpperCase refers to the method that should be called on a string, str.toUpperCase() where str is some string variable. We'll opt to refer to methods using this notation because some methods can be called on multiple data types, such as Array#slice and String#slice.

What can Array#splice do?

Before we explore the nitty-gritty details of the Array#splice method, the first thing to be aware of is that the method will mutate the array that it is called on. That is, Array#splice will modify the existing array and not return a new array.

Using splice to remove

The usage of the Array#splice method is easy to mix up because it can be used to remove or insert elements into an array. That's right - it can perform "opposite" operations, even at the same time! For now, we'll begin by only removing elements from an array:

let colors = ["red", "yellow", "blue", "green", "orange", "brown", "gray"];
let returnVal = colors.splice(2, 3);
console.log(colors); // [ 'red', 'yellow', 'brown', 'gray' ]
console.log(returnVal); // [ 'blue', 'green', 'orange' ]

The first two arguments for splice correspond to 1) the target index and 2) how many elements to remove. The call colors.splice(2, 3), will remove the next three elements beginning at index 2. This means that the elements at indices 2, 3, and 4 are removed.

Note that splice returns an array containing the elements that were removed and also has the effect of removing the elements from the original array, mutating it in-place.

Using splice to insert

To use the splice method to insert new elements into an array, we can pass in any number of additional arguments representing the values to insert:

let colors = ["red", "yellow", "blue"];
let returnVal = colors.splice(1, 0, "RebeccaPurple", "CornflowerBlue");
console.log(colors); // [ 'red', 'RebeccaPurple', 'CornflowerBlue', 'yellow', 'blue' ]
console.log(returnVal); // []

The method call colors.splice(1, 0, 'RebeccaPurple', 'CornflowerBlue') translates to "target index 1, remove the next 0 elements, then insert 'RebeccaPurple' and 'CornflowerBlue'."

Using splice like a pro

Naturally, we can combine these two functionalities! Say we wanted to target index 2, remove the next 3 elements, then insert 'Gainsboro', 'Ivory', and 'Khaki':

let colors = ["red", "yellow", "blue", "green", "black", "beige"];
let removed = colors.splice(2, 3, "Gainsboro", "Ivory", "Khaki");
console.log(colors); // [ 'red', 'yellow', 'Gainsboro', 'Ivory', 'Khaki', 'beige' ]
console.log(removed); // [ 'blue', 'green', 'black' ]

Bam. What a versatile method! Always feel free to reference the documentation for the method when you are struggling to remember its usage:

Remember

  • Array#splice has two required arguments
    • the target index
    • the number of elements to remove beginning at that target index
  • Array#splice can also take in any number of values to be inserted at the target index

String#split and Array#join

We've seen previously that strings and arrays share many similar properties. For example, strings and arrays both have a length and can have multiple indices. Because of this, you may find it useful to "convert" between the two types.

When you finish this article, you should be able to:

  • use the String#split method to turn a string into an array
  • use the Array#join method to turn an array into a string

String#split

The String#split method is called on a string and accepts a "separator" string as an argument. The method will return an array where the elements are the resulting substrings when we cut at the "separators":

let sentence = "follow the yellow brick road";
let words = sentence.split(" ");
console.log(words); // [ 'follow', 'the', 'yellow', 'brick', 'road' ]
console.log(sentence); // 'follow the yellow brick road'

Note that the original string is not mutated, rather a new array is returned. A common pattern is to split a sentence string on a space (' '), but you can split on any separator as you see fit:

let sentence = "follow the yellow brick road";
console.log(sentence.split(" ")); // [ 'follow', 'the', 'yellow', 'brick', 'road' ]
console.log(sentence.split("the")); // [ 'follow ', ' yellow brick road' ]
console.log(sentence.split("o")); // [ 'f', 'll', 'w the yell', 'w brick r', 'ad' ]

A pattern you may find useful is that when you split on a separator string, it is guaranteed that that separator will not be in the resulting array, effectively removing it. See the example of sentence.split('the') above. This may come in handy, so keep it in mind!

Array#join

The Array#join method is called on an array and accepts a "separator" string as an argument. The method will return a string where elements of the array are concatenated together with the "separator" between each element:

let words = ["run", "around", "the", "block"];
let sentence = words.join(" ");
console.log(sentence); // 'run around the block'
console.log(words); // [ 'run', 'around', 'the', 'block' ]

console.log(words.join("_")); // 'run_around_the_block'
console.log(words.join("HI")); // 'runHIaroundHItheHIblock'

Array#join does not mutate the original array, instead it will return a new string.

A clever combination

It's pretty evident that String#split and Array#join are "opposite" methods. That is:

  • we use split to turn a string into a array
  • we use join to turn an array into a string

By combining these two methods we can accomplish some cool behavior:

let str = "I don't know what I want to eat";
let newStr = str.split("I").join("we");
console.log(newStr); // 'we don't know what we want to eat'

Whoa! We were able to replace every substring "I" with the substring "we". We know that the line str.split('I').join('we') evaluates from left to right. This means that the split will cut the string wherever there is an 'I', leaving a gap where the 'I's were. Then, the join will fill those gaps with 'we's.

Remember

  • we can use String#split and Array#join to convert between strings and arrays
  • both methods do not mutate their input

WEEK-01 DAY-5
Control Flow {ignore=true}


Determining Types

Sometimes you want to know the type of value store in a variable so that you can safely do things with it. If your function expects an array in its parameter but gets a number, you can't call the map method on that!

In this article you will learn how to figure out if a value in a variable is

  • A string
  • A number
  • A function
  • An array

The typeof operator

Not all operators in JavaScript require two arguments like the + operator for addition, the = for assignment, and the % operator for modulo division. Those are all called binary operators because they take two (bi-) operands, or things that are operated on.

JavaScript kindly gives you the operator typeof which acts on a single value. Operators that take only one operand are called unary operators because "u only give them one value!" (That's a joke. "uni-" or "una-" is one.)

Here are some examples of what you'd expect to see with the typeof operator.

let s = 'This is a string';
console.log(typeof s);    // 'string'

let n = 6.28;
console.log(typeof n);    // 'number'

let sum = function (a, b) {
  return a + b;
}
console.log(typeof sum);  // 'function'

Note that the value returned from the typeof operator is a String data type. So, if you want to check if a value is a number, you could do this.

if (typeof n === 'number') {
  // It is a number. Do some maths!
} else {
  console.log('I really wanted a number. :-(');
}

How to tell if a value is an array

Unfortunately, due to a really old bug in the way that JavaScript works, a bug that no one can fix because people wrote code that relies on the bug for decades, you cannot use the typeof operator to figure out if something is an array.

let a = [1, 2, 3];
console.log(typeof a);  // 'object'

Gee, JavaScript. That's not helpful. Thanks.

Luckily, it only took 12 years for JavaScript to include a way to test if a value is an array. To do so, you use the Array.isArray method like this.

let a = [1, 2, 3];
Array.isArray(a);  // true

let n = 6.28;
Array.isArray(n);  // false

let f = function () {}
Array.isArray(f);  // false

Practical use in "real" code

Oddly enough, you won't see a lot of code in real-world applications testing if a value is one type or another. A lot of JavaScript functions just assume that they will get arguments of the right kind because the parameter names imply what kind of value to pass in. For example, the following function has a parameter named sentence.

function reverseTheSentence(sentence) {
  // ... code here ...
}

Most developers will know that the function probably wants sentence to be a string value. They just won't pass in an array or number or ... well, anything other than a string. Because that's just not polite. They'd expect any other kind of value to cause the reverseTheSentence to malfunction. Only when you know that people that don't respect your code will use it should you add in some kind of check like this.

function reverseTheSentence(sentence) {
  if (typeof sentence !== 'string') {
    // Tell the developer they are using
    // the function wrong.
  }
  // ... code here ...
}

Remember

This article has shown you two ways to determine if a value is a kind of type:

  • the typeof operator to use to test if a value is a number, a string, or a function; and,
  • the Array.isArray method to check if a value is an array.

Use them as much (or as little) as you need!


The Null Type (And Undefined)

You've met numbers and string, Booleans and arrays. There's another type often used in JavaScript: the Null type. And, it's a special type.

In this article, you will learn about the Null type, its value, and how to work with it in JavaScript.

A type with only one value

You have seen that the String type can have an "infinite" number of values (within the limits of your computer memory). For example, the String type represents any of the following values.

// Examples of values with the String type
'hello, world'
"this is a string"
`Where is my pudding?`
''
'A really long string.........................................................'

The Number type also has this aspect. Any number that you can reasonable express in JavaScript has the Number type.

// Examples of values with the Number type
-100
99
6.28
Infinity

You also know about the Boolean type. It can have only two values.

// The only two values of Boolean type
true
false

There are not more Boolean values. You can't dream up more. There are only two, those two.

The Null type has one and exactly one value.

// The only value that has the Null type
null

It's just that word: null. No quotation marks. No other fancy things. Just null.

The meaning of null

This is a harder subject to tackle because it's a philosophical subject. Many people ask, "What does the value of null mean in a program?" There are a couple of answers that programmers give to this. None of them are wrong. None of them are right. They just are. In the presence of null, the code you write determines which of the following meanings null has.

  • The value null means the absence of a value or no value
  • The value null means an unknown value
  • The value null is a nuisance and I hate it and wish it were never invented

During your software programming career, you will likely have all three of those opinions, sometimes at the same time. Let's take a look at some examples to try to figure this out.

The absence of a value

Let's say you wrote a function that splits a string into words, reverses them, and puts them back together in reverse order. You can do that with the methods

  • String#split link;
  • Array#reverse link; and,
  • Array#join link.

That function could look like this.

function reverseTheSentence(sentence) {
  let parts = sentence.split(' ');
  parts.reverse();
  return parts.join(' ');
}

That's great! It works! But, what happens if someone doesn't care about what your function and just decides to pass in something that's not a string? It would make sense that reversing something that is not a string should lead to no value, the absence of a value, because the input to the function doesn't make sense. In that case, you can just return a null because there is no value that the function can return that would make sense.

function reverseTheSentence(sentence) {
  if (typeof sentence !== 'string') {
    return null;
  }
  let parts = sentence.split(' ');
  parts.reverse();
  return parts.join(' ');
}

An unknown value

There are a lot of programmers that will argue that null cannot be an unknown value. "The value is known!" they'll exclaim. "The value is 'null'! It's known! It's 'null'! Stop saying it's not known!"

There are programmers that vehemently disagree with that.

shrug

Checking if a value is null

If you had hoped that you could use the typeof operator to check if a value is null, then you're out of luck.

// Useless code.
console.log(typeof null);  // 'object'

Silly JavaScript. Instead of using the typeof operator, you can just compare the value to null because there is only one value of the Null data type and it's always null. Take a look at the following code and figure out what you think it will produce.

let a = [];
let x = null;

if (a === null) {
  console.log('a is null');
} else if (x === null) {
  console.log('x is null');
}

Oh, and there's that undefined value, too

Just like the null value that is the only value of the Null data type, there is undefined which is the only value of the Undefined data type.

If you're asking yourself, "Wait, if 'null' is no value or the absence of a value, then what the heck does 'undefined' mean?", well you're not the only one.

Have a look at this code.

let value;

value = 6.28;
console.log(value);

You probably will not be surprised to see that it will print out "6.28" because that's the value of value. But, what if you did this? What does that new console.log print?

let value;
console.log(value); // <- what does this print?

value = 6.28;
console.log(value);

If you guessed that it prints "undefined", you're right! When you declare a variable, it's very first value is undefined. Most of the time, though, you'll just immediately set it to a value.

let value = 6.28;

So, an uninitialized variable has the value undefined which is the only value of the Undefined data type. To test for it, you can use the typeof operator or the strict equality operator. Using the strict equality operator is the more common way to do that, now.

// Test if a value is undefined
if (value === undefined) {
  // do a thing
}

// You can also do it this way, but
// it is considered passé.
if (typeof value === 'undefined') {
  // do a thing
}

What happens when...

Interestingly enough, all functions actually do return values. Have a look at this function. What value does it return? (Not a trick question.)

function returnsTrue() {
  return true;
}

Yes, it returns the value true. But, what about this function?

function returnsWhat() {
  return;
}

There's a return statement there but it does not specify a value. If there is not value specified, what do you think this function returns? Try putting the function definition above and the code below into a code runner and seeing what happens.

console.log(returnsWhat());

One you figure that out, try the same experiment but with this function. What do you think it returns. It doesn't even have a return statement in it!

function whatIsThis() {
}

Remember

There is a special value in JavaScript represented as null which means "no value" or "unknown value". It is the only value of the Null data type. You can check that a value is null by using the strict equality operator x === null.

The value undefined is used by JavaScript for variables that have not been assigned a value. Also, functions that do not return an explicit value return the value undefined. You can test if a value is undefined by using the strict equality operator x === undefined.


Catch Me If You Can

Sometimes bad things happen to good programs. Some person may enter some badly formatted information. Another computer may try to attack your program by sending it wonky data. A network could go down. A file can become corrupt. When this happens, your running software will have some errors. This article is about how you can recover from those errors with "structured exception handling".

In this article you'll learn the answers to:

  • What is structured exception handling?
  • How can I do that in JavaScript?
  • How can I make my own errors?
  • What else can I do with it?
  • Shouldn't I just always do this?

Structured exception handling

Oddly enough, there are very few error-handling mechanisms in use, today, in all programming languages. There are really only three ways that programming language provide structured exception handling.

  • Error or error code reporting as found in languages like C and Go
  • Continuable exceptions as found in Common Lisp
  • Stack unwinding which is found in almost every modern programming language including JavaScript and Python

In the stack-unwinding paradigm, which is the one you'll use in JavaScript, when an error occurs, the JavaScript interpreter (the thing running your JavaScript code) looks for some kind of handler for that error. It has a very specific way of searching for those handlers. The way JavaScript searches for the handlers is very similar to the way it happens in Python, C++, Java, C#, and a lot of other languages. Once you learn it, here, you will be able to handle errors when writing code in all of those languages.

Try and catch

Say you have some code that may have an error. For example:

function sumArray(array) {
  let sum = 0;
  for (let i = 0; i < array.length; i += 1) {
    sum += array[i];
  }
  return sum;
}

If someone calls the above function with the code sumArray(null), then they will get the error because the for loop is trying to get the length property of the array parameter which is null.

TypeError: Cannot read property 'length' of null

To prevent this from ruining your program, you wrap code that may have an error in a try block. Now, you've seen other blocks already: if blocks, for blocks, function blocks. Basically, if there are curly braces around some lines of code, that's a code block of some kind. A try block is just some curly braces with the try keyword.

// THIS IS AN INCOMPLETE BLOCK OF CODE
function sumArray(array) {
  let sum = 0;

  // The try block wraps the for loop. If some
  // error occurs, the try block will give you
  // a chance to react to it so that the program
  // doesn't terminate.
  try {
    for (let i = 0; i < array.length; i += 1) {
      sum += array[i];
    }
  } // needs something more here

  return sum;
}

The try block tells JavaScript that it needs to watch the code inside the curly braces for an error. Now, you have to tell JavaScript what to do when there is an error. You do that in the catch block that should immediately follow the try block. The catch block accepts a single parameter that (usually) contains an object that describes the error that occurred. In the case of the sumArray method, if an error occurs, you could return the value undefined rather than letting an error terminate your program. You could also log the error to the "error" output.

function sumArray(array) {
  let sum = 0;

  try {
    for (let i = 0; i < array.length; i += 1) {
      sum += array[i];
    }
  } catch (e) {
    console.log(e);
    return null;
  }

  return sum;
}

sumArray(null);

Just to state it, again: the catch block runs when an error occurs in the try block. If no error occurs in the try block, the catch block does not run.

That (e) after the word catch is a variable that contains any error that was thrown and caught by this try-catch block. It doesn't have to be named e.

function sumArray(array) {
  let sum = 0;

  try {
    for (let i = 0; i < array.length; i += 1) {
      sum += array[i];
    }
  } catch (pancakes) {
    console.log(pancakes);
    return null;
  }

  return sum;
}

sumArray(null);

Here is the same code but, instead of a variable named "e", there is a variable named "pancakes". Now, if an error is thrown, the variable "pancakes" will contain it. By long-standing tradition, the variables used with the catch block are normally "e", "err", or "error".

// CODE SNIPPET, WILL NOT RUN
} catch (e) {
// CODE SNIPPET, WILL NOT RUN
} catch (err) {
// CODE SNIPPET, WILL NOT RUN
} catch (error) {

Now, when you run the code sumArray(null), you should see something like the following, if you run it in the online code editor.

TypeError: Cannot read property 'length' of null
  at sumArray (/tmp/file.js:5:31)
  at Object.<anonymous> (/tmp/file.js:16:1)
  at Module._compile (internal/modules/cjs/loader.js:1158:30)
  at Object.Module._extensions..js (internal/modules/cjs/loader.js:1178:10)
  at Module.load (internal/modules/cjs/loader.js:1002:32)
  at Function.Module._load (internal/modules/cjs/loader.js:901:14)
  at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:74:12)
  at internal/main/run_main_module.js:18:47

In that code sample, after the sumArray(null) call, the lines that begins TypeError is the error that occurred. The next 10 lines are what is known as a stack trace. You'll end up seeing these a lot, most likely, as you continue your career in software programming. This is the first line in understanding errors in your code. The stack trace shows on the first line where the error occurred: sumArray (/tmp/file.js:5:31) means that it occurred in the sumArray method on line 5 of the content, at character 31. If you open up one of the coding problems, paste that code block in, and run it, you'll see similar output in the output block.

The last line undefined is the return value of the sumArray(null) invocation that now happens when an error occurs.

That is how the so-called try-catch block works.

How can I make my own errors?

To create your own errors with structured exception handling, you first need to create an error object with the message that describes the error. Then, you need to "throw" the error. That code would look like either of these two lines, the only difference being the new keyword. They both work exactly the same.

throw Error('this happened because I wanted it to');
throw new Error('this happened because I wanted it to');

What else is there?

Turns out that you can have one more block on the try-catch block. It is the finally block. The finally block runs whether or not an error occurs. It always runs.

function sumArray(array) {
  let sum = 0;

  try {
    for (let i = 0; i < array.length; i += 1) {
      sum += array[i];
    }
  } catch (e) {
    console.log(e);
    return null;
  } finally {
    console.log('you will always see this.');
  }

  return sum;
}

How do I best use this?

At this point, you may be asking yourself, "Self, since errors can occur everywhere, shouldn't I just wrap all of my code in these try-catch blocks?"

No. No, you shouldn't.

Every try-catch block introduces another slow-down in your code. If you're writing code that you want to run as fast as possible, then you write as few try-catch blocks as possible. Also, it makes the code pretty cluttered with all of the indentation and curly braces. When at all possible, you should write defensive code which checks for bad values before errors get thrown in your code. Rather than using a try-catch block in the sumArray function, you could defend against bad values of the array parameter like so.

function sumArray(array) {
  if (array === null) {
    return null;
  }

  let sum = 0;
  for (let i = 0; i < array.length; i += 1) {
    sum += array[i];
  }
  return sum;
}

Review

The try-catch-finally block is a mechanism to handle errors in your code. You should not wrap all of your code in these blocks because it can seriously degrade the performance of your application. Instead, only wrap those portions of the code that you want to guard against throwing exceptions.

A better choice, in JavaScript and all programming languages, is to be defensive about your programming and choose to check that the value that you have has the functionality that you desire by adding code like

if (value !== undefined) {}
if (value !== null) {}

_Resources/node_modules/jquery/

jQuery

jQuery is a fast, small, and feature-rich JavaScript library.

For information on how to get started and how to use jQuery, please see jQuery's documentation. For source files and issues, please visit the jQuery repo.

If upgrading, please see the blog post for 3.6.0. This includes notable differences from the previous version and a more readable changelog.

Including jQuery

Below are some of the most common ways to include jQuery.

Browser

Script tag

<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>

Babel

Babel is a next generation JavaScript compiler. One of the features is the ability to use ES6/ES2015 modules now, even though browsers do not yet support this feature natively.

import $ from "jquery";

Browserify/Webpack

There are several ways to use Browserify and Webpack. For more information on using these tools, please refer to the corresponding project's documentation. In the script, including jQuery will usually look like this...

var $ = require( "jquery" );

AMD (Asynchronous Module Definition)

AMD is a module format built for the browser. For more information, we recommend require.js' documentation.

define( [ "jquery" ], function( $ ) {

} );

Node

To include jQuery in Node, first install with npm.

npm install jquery

For jQuery to work in Node, a window with a document is required. Since no such window exists natively in Node, one can be mocked by tools such as jsdom. This can be useful for testing purposes.

const { JSDOM } = require( "jsdom" );
const { window } = new JSDOM( "" );
const $ = require( "jquery" )( window );
_Resources/node_modules/loadashes6/lodash/
_Resources/node_modules/mout/

mout changelog

v1.1.1 (2019/04/18)

  • fixed object/get throwing an exception for null or undefined input objects

v1.1.0 (2017/10/04)

  • update dependencies
  • optimize function/bind
  • optimize lang/kindOf

v0.12.0 (2016/03/03)

  • add array/indicesOf
  • add function/memoize
  • add array/reverse
  • add math/overflow
  • fix query/getQuery
  • fix object/deepMatches
  • optimize function/partial
  • updates license

v0.11.0 (2014/11/17)

  • add array/take;
  • remove unused variable from date/totalDaysInMonth;
  • fix case insensitive RegExp cloning on lang/clone;

v0.10.0 (2014/09/02)

  • add array/equals;
  • add array/groupBy;
  • add array/last;
  • add function/wrap;
  • add lang/GLOBAL;
  • add lang/isPrimitive;
  • add number/MAX_SAFE_INTEGER;
  • add object/omit;
  • add object/result;
  • add object/result;
  • add random/randString;
  • change lang/isEmpty behavior to return true for any value that isn't a collection.
  • fix array/findLastIndex to stop at zero index;
  • improve function/partial to accept placeholders;
  • improve math.norm behavior for values outside the range and for cases where val === min === max;
  • improve object/get behavior to return properties from any value that is not null or undefined;
  • move object/deepEquals to lang/deepEquals (improving the behavior);

v0.9.1 (2014/04/08)

  • fix array/slice behavior when start and end are higher than length.

v0.9.0 (2014/02/04)

  • add date/quarter;
  • add function/constant;
  • add random/randBool;
  • add un-padded 12-hour (%l) to date/strftime;
  • fix array/slice on IE < 9 by using a custom implementation.
  • fix object/forIn iteration for IE < 9 constructor property;
  • improve lang/inheritPrototype by returning the prototype;
  • improve string/removeNonWord to cover more chars;
  • improve string/repeat performance;
  • improve string/unescapeHtml by accepting leading zeros for &#39;

v0.8.0 (2013/11/22)

  • add array/findLast.
  • add array/findLastIndex.
  • add array/slice and use it internally.
  • add array/sortBy
  • add function/awaitDelay.
  • add function/identity
  • add number/isNaN.
  • add number/nth.
  • add number/ordinal.
  • allows nested replacement patterns in string/interpolate.
  • change function/makeIterator_ behavior (uses identity by default).
  • simplify string/escapeRegExp.
  • support custom equality on array/compare.

v0.7.1 (2013/09/18)

  • fix null value handling in object/get.

v0.7.0 (2013/09/05)

  • add bower ignores.
  • add german translation for date localization.
  • alias function package as fn since "function" is a reserved keyword.
  • allow second argument on array/pick.
  • improve string/makePath to not remove "//" after protocol.
  • make sure methods inside number package works with mixed types.
  • support arrays on queryString/encode.
  • support multiple values for same property on queryString/decode.
  • add cancel() method to throttled/debounced functions.
  • add function/times.
  • add lang/toNumber.
  • add string/insert.
  • add super_ to constructor on lang/inheritPrototype.

v0.6.0 (2013/05/22)

  • add optional delimeter to string/unCamelCase
  • allow custom char on number/pad
  • allow underscore characters in string/removeNonWord
  • accept level on array/flatten instead of a flag
  • convert underscores to camelCase in string/camelCase
  • remove create() from number/currencyFormat
  • add date/dayOfTheYear
  • add date/diff
  • add date/isSame
  • add date/startOf
  • add date/strftime
  • add date/timezoneAbbr
  • add date/timezoneOffset
  • add date/totalDaysInYear
  • add date/weekOfTheYear
  • add function/timeout
  • add object/bindAll
  • add object/functions
  • add time/convert

v0.5.0 (2013/04/04)

  • add array/collect
  • add callback parameter to object/equals and object/deepEquals to allow custom compare operations.
  • normalize behavior in array/* methods to treat null values as empty arrays when reading from array
  • add date/parseIso
  • add date/isLeapYear
  • add date/totalDaysInMonth
  • add object/deepMatches
  • change function/makeIterator_ to use deepMatches (affects nearly all iteration methods)
  • add thisObj parameter to array/min and array/max

v0.4.0 (2013/02/26)

  • add object/equals
  • add object/deepEquals
  • add object/matches.
  • add lang/is and lang/isnt.
  • add lang/isInteger.
  • add array/findIndex.
  • add shorthand syntax to array/*, object/* and collection/* methods.
  • improve number/sign behavior when value is NaN or +0 or -0.
  • improve lang/isNaN to actually check if value is not a number without coercing value; so [], "", null and "12" are considered NaN (#39).
  • improve string/contains to match ES6 behavior (add fromIndex argument).

v0.3.0 (2013/02/01)

  • add lang/clone.
  • add lang/toString.
  • add string/replace.
  • add string/WHITE_SPACES
  • rename function/curry to function/partial.
  • allow custom chars in string/trim, ltrim, and rtrim.
  • convert values to strings in the string/* functions.

v0.2.0 (2013/01/13)

  • fix bug in math/ceil for negative radixes.
  • change object/deepFillIn and object/deepMixIn to recurse only if both existing and new values are plain objects. Will not recurse into arrays or objects not created by the Object constructor.
  • add lang/isPlainObject to check if a file is a valid object and is created by the Object constructor
  • change lang/clone behavior when dealing with custom types (avoid cloning it by default) and add second argument to allow custom behavior if needed.
  • rename lang/clone to lang/deepClone.
  • add VERSION property to index.js
  • simplify math/floor, math/round, math/ceil and math/countSteps.

v0.1.0 (2013/01/09)

  • Rename project from "amd-utils" to "mout"

Contributing

Fork the repo at https://github.com/mout/mout

"Write clearly, don't be too clever" - The Elements of Programming Style

Avoid unnamed functions and follow the other modules structure. By only using named functions it will be easier to extract the code from the AMD module if needed and it will also give better error messages, JavaScript minifiers like Google Closure Compiler and UglifyJS will make sure code is as small/optimized as possible.

"Make it clear before you make it faster." - The Elements of Programming Style

Be sure to always create tests for each proposed module. Features will only be merged if they contain proper tests and documentation.

"Good code is its own best documentation." - Steve McConnell

We should do a code review before merging to make sure names makes sense and implementation is as good as possible.

Try to split your pull requests into logical groups, the smaller the easier to be reviewed/merged.

Tests & Code Coverage

Tests can be found inside the tests folder, to execute them in the browser open the tests/runner.html. The same tests also work on node.js by running npm test.

We should have tests for all methods and ensure we have a high code coverage through our continuous integration server (travis). When you ask for a pull request Travis will automatically run the tests on node.js and check the code coverage as well.

We run node build pkg automatically before any npm test, so specs and packages should always be in sync. (will avoid human mistakes)

To check code coverage run npm test --coverage, it will generate the reports inside the coverage folder and also log the results. Please note that node.js doesn't execute all code branches since we have some conditionals that are only met on old JavaScript engines (eg. IE 7-8), so we will never have 100% code coverage (but should be close to it).

Build Script

The build script can be extremely helpful and can avoid human mistakes, use it.

Admins / Pull Requests

Even if you are an admin (have commit rights) please do pull requests when adding new features or changing current behavior, that way we can review the work and discuss. Feel free to push changes that doesn't affect behavior without asking for a pull request (readme, changelog, build script, typos, refactoring, ...).

Large changes

If you are proposing some major change, please create an issue to discuss it first. (maybe it's outside the scope of the project)

Questions / IRC / Wiki / Issue Tracker

When in doubt ask someone on IRC to help you (#moutjs on irc.freenode.net) or create a new issue.

The project wiki can also be a good resource of information.


Check the contributors list at github.

_Resources/node_modules/mout/doc/

array

Array utilities.

append(arr1, arr2):Array

Appends an array to the end of the other. The first array will be modified and will contain the appended items.

See: union(), combine()

var foo = ['a', 'b'],
    bar = ['b', 'd'];

append(foo, bar); // ['a', 'b', 'b', 'd']

collect(arr, callback, [thisObj]):Array

Maps the items in arr and concatenates the resulting arrays.

See: map()

collect([1, 2, 3], function(val) {
    return [val, val % 2];
}); // [1, 1, 2, 0, 3, 1];

collect(['a', 'bb', ''], function(val) {
    return val.split('');
}); // ['a', 'b', 'b']

It also supports a shorthand syntax:

var items = [{ a: [1] }, { b: 'foo' }, { a: [2, 3] }];
collect(items, 'a'); // [1, 2, 3];

combine(arr1, arr2):Array

Combines an array with all the items of another. The first array will be modified and will contain the combined items. Does not allow duplicates and is case and type sensitive.

See: union(), append()

var foo = ['a', 'b'],
    bar = ['b', 'd'];

combine(foo, bar); // ['a', 'b', 'd']

compact(arr):Array

Returns a new Array without any null or undefined values. Note that it will keep empty strings and other falsy values (simillar to Ruby Array#compact).

var arr = [0, 1, null, false, '', 'foo', undefined, 'bar'];
compact(arr); // [0, 1, false, '', 'foo', 'bar'];

contains(arr, value):Boolean

Checks if Array contains value. Alias to indexOf(arr, val) !== -1.

var arr = [1, 2, 3];
contains(arr, 2);      // true
contains(arr, 'foo');  // false

difference(...arrs):Array

Return a new Array with elements that aren't present in the other Arrays besides the first one.

Works like Python set#difference.

It will remove duplicates.

See: xor(), intersection()

var a = ['a', 'b', 1];
var b = ['c', 1];
difference(a, b); // ['a', 'b']

equals(a, b, [compare]):Boolean

Checks if both arrays are equal.

equals([1, 2], [1, 2]); // true
equals([2, 4], [1, 2]); // false

By default it uses the lang/is as the compare function but you can pass a custom function to change the behavior.

function loose(a, b) {
    return a == b;
}
equals(['1', 2], [1, 2], loose); // true

See: object/equals, lang/deepEquals

every(arr, callback, [thisObj]):Array

Crossbrowser Array.every().

Tests whether all elements in the array pass the test implemented by the provided function.

It differs from ES5 since it will also loop over sparse items in the array to normalize the behavior across browsers (avoid inconsistencies).

var items = [1, 'foo', 'bar'];
every(items, isString);   // false
every(items, isFunction); // false
every(items, function(val, key, arr){
    return val != null;
}); // true

more info at MDN Array#every

It also supports a shorthand syntax:

var items = [{id:1, active:true}, {id:3, active:true}, {id:8, active:true}];
// all items with `id === 8`
every(items, {id:8}); // false
// `active` is truthy on all items
every(items, 'active'); // true

filter(arr, callback, [thisObj]):Array

Crossbrowser Array.filter().

Creates a new array with all elements that pass the callback test.

It differs from ES5 since it will also loop over sparse items in the array to normalize the behavior across browsers (avoid inconsistencies).

var nums = [1, 2, 3, 4, 5, 6];
var oddNumbers = filter(nums, function(val, key, arr){
    return (val % 2) !== 0;
});
// > [1, 3, 5]

more info at MDN Array#filter

Filter also supports shorthand notation:

var users = [
    {name:'john', surname:'connor', beard:false},
    {name:'john', surname:'doe', beard:true},
    {name:'jane', surname:'doe', beard:false}
];
// filter item that matches all properties/values pairs
filter(users, {name:'john', beard:false});
// > [{name:'john', surnname:'connor', beard:false}]
// items where 'beard' is a truthy value
filter(users, 'beard');
// > [{name:'john', surnname:'doe', beard:true}]

See reject()

find(arr, callback, [thisObj]):*

Loops through all the items in the Array and returns the first one that passes a truth test (callback).

var arr = [123, {a:'b'}, 'foo', 'bar'];
find(arr, isString); // "foo"
find(arr, isNumber); // 123
find(arr, isObject); // {a:'b'}

Find also supports shorthand notation:

var users = [
    {name:'john', surname:'connor', beard:false},
    {name:'john', surname:'doe', beard:true}
];
// first item that matches all properties/values pairs
find(users, {name:'john'}); // {name:'john', surnname:'connor', beard:false}
// first item where 'beard' is a truthy value
find(users, 'beard'); // {name:'john', surnname:'doe', beard:true}

See: findIndex(), findLast(), findLastIndex()

findLast(arr, callback, [thisObj]):*

Loops through all the items in the Array (starting from last item) and returns the first one that passes a truth test (callback).

var arr = [123, {a:'b'}, 'foo', 'bar'];
findLast(arr, isString); // "bar"
findLast(arr, isNumber); // 123
findLast(arr, isObject); // {a:'b'}

findLast also supports shorthand notation:

var users = [
    {name:'john', surname:'connor', beard:false},
    {name:'john', surname:'doe', beard:true}
];
// last item that matches all properties/values pairs
findLast(users, {name:'john'}); // {name:'john', surnname:'doe', beard:true}
// last item where 'beard' is a truthy value
findLast(users, 'beard'); // {name:'john', surnname:'doe', beard:true}

See: find(), findIndex(), findLastIndex()

findIndex(arr, iterator, [thisObj]):Number

Loops through the items in the Array and returns the index of the first one that passes a truth test (callback).

Returns -1 if no item was found that passes the truth test.

var arr = [1, { a: 1 }, 'foo', 'bar'];
findIndex(arr, isString); // 2
findIndex(arr, isNumber); // 0
findIndex(arr, isObject); // 1
findIndex(arr, isRegExp); // -1

findIndex also supports shorthand notation:

var pets = [
    { pet: 'dog', name: 'Sam' },
    { pet: 'dog', name: 'Maggie' }
];

findIndex(pets, { pet: 'dog' }); // 0
findIndex(pets, { name: 'Maggie' }); // 1

See: find(), findLastIndex()

findLastIndex(arr, iterator, [thisObj]):Number

Loops through the items in the Array on the reverse order and returns the index of the first one that passes a truth test (callback).

Returns -1 if no item was found that passes the truth test.

var arr = [1, { a: 1 }, 'foo', 'bar'];
findLastIndex(arr, isString); // 3
findLastIndex(arr, isNumber); // 0
findLastIndex(arr, isObject); // 1
findLastIndex(arr, isRegExp); // -1

findLastndex also supports shorthand notation:

var pets = [
    { pet: 'dog', name: 'Sam' },
    { pet: 'dog', name: 'Maggie' }
];

findLastIndex(pets, { pet: 'dog' }); // 1
findLastIndex(pets, { name: 'Sam' }); // 0

See: find(), findIndex()

flatten(arr, [level]):Array

Recursively flattens an array. A new array containing all the elements is returned. If level is specified, it will only flatten up to that level. Note that arrays within objects will not be flattened.

Example

flatten([1, [2], [3, [4, 5]]]);
// > [1, 2, 3, 4, 5]
flatten([1, [2], [3, [4, 5]]], 1);
// > [1, 2, 3, [4, 5]]

See: object/flatten()

forEach(arr, callback, [thisObj]):void

Crossbrowser Array.forEach().

It allows exiting the iteration early by returning false on the callback.

It differs from ES5 since it will also loop over sparse items in the array to normalize the behavior across browsers (avoid inconsistencies).

var items = ['foo', 'bar', 'lorem', 'ipsum'];
forEach(items, function(val, key, arr){
    console.log(key +' : '+ val);
    if (val === 'lorem') {
        // stop iteration (break)
        return false;
    }
});

more info at MDN Array#forEach

groupBy(arr, [categorize=identity], [thisObj]):Object

Groups array elements by the key returned from the categorize function.

It will use the function/identity as the default categorize function.

var items = ['lorem', 'ipsum', 'foo', 'bar', 'baz'];
groupBy(items, function(val) { return val.length });
// > {'3': ['foo', 'bar', 'baz'], '5': ['lorem', 'ipsum']}

indexOf(arr, item, [fromIndex]):Number

Crossbrowser Array.indexOf().

It differs from ES5 since it will also loop over sparse items in the array to normalize the behavior across browsers (avoid inconsistencies).

more info at MDN Array#indexOf

indicesOf(arr, item, [fromIndex]):Number

Returns an array of indices where item is found in the array.

Like array/indexOf it does loop over sparse items in the array. The optional fromIndex parameter can limit the scope, the same way as it does in indexOf.

var items = ['lorem', 'ipsum', 'foo', 'ipsum', 'ipsum'];

indicesOf(items, 'ipsum');
// > [1, 3, 4]

indicesOf(items, 'ipsum', 1);
// > [3, 4]

insert(arr, ...items):Number

Push items into array only if they aren't contained by it. Returns the new length of the array.

See: remove(), removeAll(), contains()

var arr = ['a', 'b'];
insert(arr, 'a');       // 2 : ['a', 'b']
insert(arr, 'c');       // 3 : ['a', 'b', 'c']
insert(arr, 1, 2, 'b'); // 5 : ['a', 'b', 'c', 1, 2]

intersection(...arrs):Array

Return a new Array with elements common to all Arrays.

Similar to Python set#intersection and underscore.js intersection.

It will remove duplicates.

See: difference(), xor()

var a = ['a', 'b', 1],
    b = ['c', 1],
    c = [1, 2, 3];
intersection(a, b, c); // [1]

invoke(arr, methodName[, ...args]):Array

Call methodName on each item of the array passing custom arguments if needed.

invoke([[3,2,1], [9,5,2]], 'sort'); // [[1,2,3], [2,5,9]]

join(arr, [separator]):String

Joins the strings in arr, inserting separator between each value.

This ignores null values and empty strings that are in the array. separator defaults to an empty string. This will convert all non-string objects in the array to a string.

Example

join(['a', 'b', 'c']); // 'abc'
join(['foo', 'bar'], ', '); // 'foo, bar'
join([null, 'foo', '', 'bar', undefined], ':'); // 'foo:bar'

last(arr):*

Returns the last element of an array without modifying the array.

last( [1, 2, 3, 4] ) // > 4
last( ['foo', 'bar'] ) // > 'bar'

lastIndexOf(arr, item, [fromIndex]):Number

Crossbrowser Array.lastIndexOf().

It differs from ES5 since it will also loop over sparse items in the array to normalize the behavior across browsers (avoid inconsistencies).

more info at MDN Array#lastIndexOf

map(arr, callback, [thisObj]]):Array

Crossbrowser Array.map().

Creates a new array with the results of calling a provided function on every element in this array.

It differs from ES5 since it will also loop over sparse items in the array to normalize the behavior across browsers (avoid inconsistencies).

See: collect()

var nums = [1,2,3,4];
var double = map(nums, function(val, key, arr){
    return val * 2;
});
// > [2, 4, 6, 8]

more info at MDN Array#map

It also supports a shorthand notation which can be used to achieve same result as array/pluck:

var src = ['lorem', 'ipsum', 'foo', 'amet'];
// grab the "length" property of all items
var lengths = map(src, 'length'); // [5, 5, 3, 4]

max(arr, [iterator], [thisObj]):*

Returns maximum value inside array or use a custom iterator to define how items should be compared.

See: min()

max([10, 2, 7]); // 10
max(['foo', 'lorem', 'amet'], function(val){
    return val.length;
}); // 'lorem'

It also supports a shorthand notation:

max(['foo', 'lorem', 'amet'], 'length'); // "lorem"

min(arr, [iterator], [thisObj]):*

Returns minimum value inside array or use a custom iterator to define how items should be compared.

See: max()

min([10, 2, 7]); // 2
min(['foo', 'lorem', 'amet'], function(val){
    return val.length;
}); // 'foo'

It also supports a shorthand notation:

min(['foo', 'lorem', 'amet'], 'length'); // "foo"

pick(arr, [nItems]):*

Gets random item(s) and removes it from the original array.

If nItems is specified it will return a new Array contained the picked items otherwise it returns a single item.

See: random/choice()

Example:

var arr = [1, 2, 3, 4, 5, 6];
var item1 = pick(arr); // 4
var item2 = pick(arr); // 1
var items = pick(arr, 2); // [5, 2]
console.log(arr); // [3, 6]

pluck(arr, propName):Array

Extract a list of property values.

See: function/prop()

var users = [{name : 'John', age: 21}, {name: 'Jane', age : 27}];
var names = pluck(users, 'name'); // ["John", "Jane"]
var ages = pluck(users, 'age'); // [21, 27]

range([start], stop[, step]):Array

Creates a new Array with all the values inside the range. Works similarly to Python#range or PHP#range.

Arguments

  1. [start] (Number) : Range start. Default is 0.
  2. stop (Number) : Range limit.
  3. [step] (Number) : Step size. Default is 1.

Example

range(5);         // [0, 1, 2, 3, 4, 5]
range(0, 5);      // [0, 1, 2, 3, 4, 5]
range(0, 5, 2);   // [0, 2, 4]
range(20, 40, 5); // [20, 25, 30, 35, 40]

reduce(arr, fn):*

Crossbrowser Array.reduce().

Apply a function against an accumulator and each value of the array (from left-to-right) as to reduce it to a single value.

It differs from ES5 since it will also loop over sparse items in the array to normalize the behavior across browsers (avoid inconsistencies).

more info at MDN Array#reduce

reduceRight(arr, fn):*

Crossbrowser Array.reduceRight().

Apply a function simultaneously against two values of the array (from right-to-left) as to reduce it to a single value.

It differs from ES5 since it will also loop over sparse items in the array to normalize the behavior across browsers (avoid inconsistencies).

more info at MDN Array#reduceRight

reject(arr, fn, thisObj):Array

Creates a new array with all the elements that do not pass the truth test. Opposite of filter().

See filter()

Example

var numbers = [1, 2, 3, 4, 5, 6];
reject(numbers, function(x) { return (x % 2) !== 0; }); // [2, 4, 6]

It also supports a shorthand syntax:

var users = [
    {name:'john', surname:'connor', beard:false},
    {name:'john', surname:'doe', beard:true},
    {name:'jane', surname:'doe', beard:false}
];
// reject items that matches all properties/values pairs
reject(arr, {name:'john'});
// > [{name:'jane', surnname:'doe', beard:false}]
// reject items where 'beard' is a truthy value
filter(arr, 'beard');
// > [{name:'john', surnname:'connor', beard:false},
//    {name:'jane', surname:'doe', beard:false}]

remove(arr, item):void

Remove a single item from the array.

IMPORTANT: it won't remove duplicates, just a single item.

Example

var foo = [1, 2, 3, 4];
remove(foo, 2);
console.log(foo); // [1, 3, 4]

removeAll(arr, item):void

Remove all instances of an item from the array.

Example

var foo = [1, 2, 3, 4, 2, 2];
removeAll(foo, 2);
console.log(foo); // [1, 3, 4];

reverse(arr):void

Returns a copy of the array with all elements in reversed order.

Example

var foo = [1, 2, 3, 4, 5];
var bar = reverse(foo);
console.log(bar); // [5, 4, 3, 2, 1];

console.log(foo); // [1, 2, 3, 4, 5];

shuffle(arr):Array

Returns a new Array with items randomly sorted (shuffled). Similar to Ruby Array#shuffle.

Example

var arr = ['a', 'b', 'c', 'd', 'e'];
shuffle(arr); // ['b', 'd', 'e', 'c', 'a']

slice(arr, [start], [end]):Array

Returns a new array containing the items from arr from the start index to the end index.

If start is omitted, it will start at 0. If end is omitted, it will used the last index of the array. If start or end is negative, it is used as an offset from the end of the array.

It will also convert array-like objects to arrays.

Example

slice([1, 2, 3, 4], 1, 2); // [2, 3]
slice([1, 2, 3], 1); // [2, 3]
slice([1, 2, 3]); // [1, 2, 3]
slice({ length: 2, 0: 'a', 1: 'b' }); // ['a', 'b']
slice([1, 2, 3], 0, -1); // [1, 2]
slice([1, 2, 3], -2); // [2, 3]

some(arr, callback, [thisObj]):Array

Crossbrowser Array.some().

Tests whether some element in the array passes the test implemented by the provided function.

It differs from ES5 since it will also loop over sparse items in the array to normalize the behavior across browsers (avoid inconsistencies).

var items = [1, 'foo', 'bar'];
some(items, isString);   // true
some(items, isFunction); // false

more info at MDN Array#some

It also supports a shorthand syntax:

var items = [{id:1, active:true}, {id:3, active:false}, {id:8, active:false}];
// at least one item with `id === 8`
some(items, {id:8}); // true
// `active` is truthy on at least one item
some(items, 'active'); // true

see also: object/matches

sort(arr, [compareFn]):Array

Returns a sorted Array using the Merge Sort algorithm (stable sort).

The Array.prototype.sort browser implementations differ since the sorting algorithm isn't described in the ES spec - in V8 it isn't stable and on Firefox it is stable - so this function doesn't use the browser native implementation and is recommended in cases where a stable sort is required (items should preserve same order if already sorted).

Important: It does logical comparisson by default (greater/less than) and not a string comparisson like the native Array#sort.

compareFn

If compareFn is supplied elements are sorted based on the value returned by the compareFn.

  • If compareFn(a, b) is less than 0, sort a to a lower index than b.
  • If compareFn(a, b) returns 0, leave a and b unchanged with respect to each other, but sorted with respect to all different elements.
  • If compareFn(a, b) is greater than 0, sort b to a lower index than a.

See: sortBy

Example

sort([187, 23, 47, 987, 12, 59, 0]); // [0, 12, 23, 47, 59, 187, 987]
sort(['a', 'z', 'c', 'beta', 'b']); // ['a', 'b', 'beta', 'c', 'z']

// ['sit', 'amet', 'lorem', 'ipsum']
sort(['lorem', 'ipsum', 'sit', 'amet'], function(a, b){
    // sort by length, items with same length
    // will keep the relative order (stable)
    return a.length - b.length;
});

// [4, 3, 2, 1]
sort([2, 3, 1, 4], function(a, b){
    // reverse sort
    return b - a;
});

sortBy(arr, callback, [context]):Array

Returns an array sorted by the result of the callback.

The callback is called for each item that is to be sorted, and the results of the callback are used to sort the array. The callback is called with the item as the first parameter, optionally with the provided context.

It also supports a shorthand notation which can be used to sort by a property name.

See: sort

// Returns [{ a: 1 }, { a: 2 }, { a: 3 }]
sortBy([{ a: 1 }, { a: 3 }, { a: 2 }],
    function(item) { return item.a; });

// Same as above, using shorthand notation
sortBy([{ a: 1 }, { a: 3 }, { a: 2 }], 'a');

split(arr, [segments]):Array

Splits an array into a fixed number of segments.

The number of segments is specified by segments and defaults to 2. If the array cannot be evenly split, the first segments will contain the extra items. If arr is empty, an empty array is returned. If arr.length is less than segments, then the resulting array will have arr.length number of single-element arrays.

Example

split([1, 2, 3, 4, 5], 3) // [ [1, 2], [3, 4], [5] ]
split([1, 2, 3, 4, 5]) // [ [1, 2, 3], [4, 5] ]
split([]) // []
split([1, 2], 3) // [ [1], [2] ]

take(times, callback, [thisObj]):Array

Builds a new array based on the returned values from the given callback.

take(4, function(i, total) {
    return i / total;
});
// > [0, 0.25, 0.5, 0.75]

see: function/times

toLookup(arr, key):Object

Create an object that indexes the items in the array by a key. If key is a function, the key for each value in the resulting object will be the result of calling the function with the value as an argument. Otherwise key specifies the property on each value to use as the key.

Example

var foo = [{ name: 'a', thing: 1 }, { name: 'b', thing: 2 }];
// { a: { name: 'a', thing: 1 }, b: { name: 'b', thing: 2 } }
toLookup(foo, 'name');
// same as above
toLookup(foo, function (value) { return value.name; });

union(...arrs):Array

Concat multiple arrays removing duplicates.

var a = ['a', 'b'],
    b = ['c', 'a'],
    c = [1, 'b', 2, 3, 'a'];

//note that unique remove from begin to end
union(a, b, c); // ['c', 1, 'b', 2, 3, 'a']

unique(arr, [compare]):Array

Return a new Array of unique items.

IMPORTANT: duplicates are removed starting from begining of array.

var arr = [1, 2, 3, 4, 2, 2, 4];
var foo = unique(arr);
console.log(foo);
// > [1, 3, 2, 4];

// you also have the option to set a custom compare function
var users = [{name: 'john'}, {name: 'paul'}, {name: 'john'}];
var uniqueNames = unique(arr, function(a, b){
    return a.name === b.name;
});
console.log(uniqueNames);
// > [{name: 'paul'}, {name: 'john'}]

xor(arr1, arr2):Array

Exclusive OR. Returns items that are present in a single array.

Works like Python set#symmetric_difference renamed for brevity.

It will remove duplicates.

See: difference(), intersection()

var a = ['a', 'b', 1];
var b = ['c', 1];
xor(a, b); // ['a', 'b', 'c']

zip(...arrs):Array

Groups the elements of each array at their corresponding indexes.

Useful for separate data sources that are coordinated through matching array indexes. For a matrix of nested arrays, zip.apply(...) can transpose the matrix in a similar fashion.

// [['moe', 30, true], ['larry', 40, false], ['curly', 50, false]]
zip(['moe', 'larry', 'curly'], [30, 40, 50], [true, false, false]);

For more usage examples check specs inside /tests folder. Unit tests are the best documentation you can get...

collection

Methods for dealing with collections (Array or Objects).

contains(list, value):Boolean

Checks if collection contains value.

contains({a: 1, b: 2, c: 'bar'}, 2); // true
contains([1, 2, 3], 'foo');  // false

See: array/contains, object/contains

every(list, callback, [thisObj]):Boolean

Tests whether all values in the collection pass the test implemented by the provided callback.

var obj = {
    a: 1,
    b: 2,
    c: 3,
    d: 'string'
};

every(obj, isNumber); // false

See: array/every, object/every

filter(list, callback, [thisObj]):Array

Filter collection properties.

See: array/filter, object/filter

find(list, callback, [thisObj]):*

Loops through all the values in the collection and returns the first one that passes a truth test (callback).

Important: loop order over objects properties isn't guaranteed to be the same on all environments.

find({a: 'foo', b: 12}, isString); // 'foo'
find(['foo', 12], isNumber); // 12

See: array/find, object/find

forEach(list, callback, [thisObj])

Loop through all values of the collection.

See: array/forEach, object/forOwn

map(list, callback, [thisObj]):Array

Returns a new collection where the properties values are the result of calling the callback for each property in the original collection.

See: array/map, object/map

max(list, [iterator]):*

Returns maximum value inside collection or use a custom iterator to define how items should be compared.

See: min(), array/max, object/max

max({a: 100, b: 2, c: 1, d: 3, e: 200}); // 200
max(['foo', 'lorem', 'amet'], function(val){
    return val.length;
}); // 'lorem'

min(list, [iterator]):*

Returns minimum value inside collection or use a custom iterator to define how items should be compared.

See: max(), array/min, object/min

min([10, 2, 7]); // 2
min({a: 'foo', b: 'lorem', c: 'amet'}, function(val){
    return val.length;
}); // 'foo'

pluck(list, propName):Array

Extract a list of property values.

var users = [
    {
        name : 'John',
        age : 21
    },
    {
        name : 'Jane',
        age : 27
    }
];

pluck(users, 'name'); // ["John", "Jane"]
pluck(users, 'age'); // [21, 27]

users = {
    first: {
        name : 'John',
        age : 21
    },
    second: {
        name : 'Mary',
        age : 25
    }
};

pluck(users, 'name'); // ['John', 'Mary']

See: array/pluck, object/pluck

reduce(list, callback, initial, [thisObj]):*

Apply a function against an accumulator and each value in the collection as to reduce it to a single value.

var obj = {a: 1, b: 2, c: 3, d: 4};

function sum(prev, cur, key, list) {
    return prev + cur;
}

reduce(obj, sum); // 10

See: array/reduce, object/reduce

reject(list, fn, [thisObj]):Array

Creates a new array with all the elements that do not pass the truth test. Opposite of filter().

Example

var numbers = [1, 2, 3, 4, 5];
reject(numbers, function(x) { return (x % 2) !== 0; }); // [2, 4]

var obj = {a: 1, b: 2, c: 3, d: 4, e: 5};
reject(obj, function(x) { return (x % 2) !== 0; }); // [2, 4]

See: array/reject, object/reject

size(list):Number

Returns the number of values in the collection.

var obj = {
    foo : 1,
    bar : 2,
    lorem : 3
};
size(obj);     // 3
size([1,2,3]); // 3
size(null);    // 0

See: object/size

some(list, callback, [thisObj]):Boolean

Tests whether any values in the collection pass the test implemented by the provided callback.

var obj = {
    a: 1,
    b: 2,
    c: 3,
    d: 'string'
};

some(obj, isNumber);      // true
some(obj, isString);      // true
some([1, 2, 3], isNumber) // true
some([1, 2, 3], isString) // false

See: array/some, object/some


For more usage examples check specs inside /tests folder. Unit tests are the best documentation you can get...

date

Date utilities.

dayOfTheYear(date):Number

How many days elapsed since begining of the year (following gregorian calendar).

// Jan 1st
dayOfTheYear(new Date(2013, 0, 1)); // 1
// Dec 31th
dayOfTheYear(new Date(2013, 11, 31)); // 364

diff(date1, date2, [unitName]):Number

Calculate the difference between dates (range).

The returned value is always positive. The default unitName is "ms".

Available units: year, month, week, day, hour, minute, second, millisecond.

See: time/convert()

var d1 = new Date(2012, 4, 5);
var d2 = new Date(2013, 4, 8);
diff(d1, d2);          // 31795200000
diff(d1, d2, 'hour');  // 8832
diff(d1, d2, 'week');  // 52.57142857142857
diff(d1, d2, 'month'); // 12.096774193548388
diff(d1, d2, 'year');  // 1.0082191780821919

isLeapYear(fullYear|date):Boolean

Checks if it's a leap year according to the Gregorian calendar.

see: totalDaysInMonth()

isLeapYear(2012); // true
isLeapYear(2013); // false
isLeapYear(new Date(2012, 2, 28)); // true

isSame(date1, date2[, period]):Boolean

Check if both dates are the "same".

You can pass an optional period used to set the comparisson precision.

Available periods: year, month, week, day, hour, minute, second.

var date1 = new Date(2013, 1, 3);
var date2 = new Date(2013, 2, 9);
isSame(date1, date2);          // false
isSame(date1, date2, 'day');   // false
isSame(date1, date2, 'month'); // false
isSame(date1, date2, 'year');  // true

parseIso(str):Number

Parses an ISO8601 date and returns the number of milliseconds since January 1, 1970, 00:00:00 UTC, or NaN if it is not a valid ISO8601 date.

This parses all ISO8601 dates, including dates without times, ordinal dates, and the compact representation (omitting delimeters). The only exception is ISO week dates, which are not parsed.

If no time zone offset is specified, it assumes UTC time.

// Jan 01, 1970 00:00 GMT
parseIso('1970-01-01T00:00:00')    // 0
parseIso('1970-001')               // 0
parseIso('1970-01-01')             // 0
parseIso('19700101T000000.00')     // 0
parseIso('1970-01-01T02:00+02:00') // 0

// Jan 02, 2000 20:10 GMT+04:00
parseIso('2000-01-02T20:10+04:00') // 946829400000

quarter(date):Number

Get a number between 1 to 4 that represents the quarter of the year.

quarter(new Date(2013, 1, 19)); // 1
quarter(new Date(2013, 4, 12)); // 2
quarter(new Date(2013, 7, 25)); // 3
quarter(new Date(2013, 10, 8)); // 4

startOf(date, period):Date

Get a new Date at the start of the period.

Available periods: year, month, week, day, hour, minute, second.

// Apr 05 2013 11:27:43
var date = new Date(2013, 3, 5, 11, 27, 43, 123);
startOf(date, 'year');  // Jan 01 2013 00:00:00
startOf(date, 'month'); // Apr 01 2013 00:00:00
startOf(date, 'day');   // Apr 05 2013 00:00:00
startOf(date, 'hour');  // Apr 05 2013 11:00:00

strftime(date, format, [l10n]):String

Format date based on strftime format.

Replaced tokens:

%a
locale's abbreviated weekday name.
%A
locale's full weekday name.
%b
locale's abbreviated month name.
%B
locale's full month name.
%c
locale's appropriate date and time representation.
%C
century number (the year divided by 100 and truncated to an integer) as a decimal number [00..99].
%d
day of the month as a decimal number [01..31].
%D
same as %m/%d/%y.
%e
day of the month as a decimal number [1..31]; a single digit is preceded by a space.
%F
The ISO 8601 date format (%Y-%m-%d)
%h
same as %b.
%H
hour (24-hour clock) as a decimal number [00..23].
%I
hour (12-hour clock) as a decimal number [01..12].
%j
day of the year as a decimal number [001..366].
%l
hour (12-hour clock) as a decimal number (range 1 to 12); single digits are preceded by a blank
%L
zero-padded milliseconds [000..999]
%m
month as a decimal number [01..12].
%M
minute as a decimal number [00..59].
%n
newline character.
%p
locale's equivalent of either "am" or "pm"
%P
locale's equivalent of either "AM" or "PM"
%r
time in a.m. and p.m. notation; in the POSIX locale this is equivalent to %I:%M:%S %p.
%R
time in 24 hour notation (%H:%M).
%s
seconds since Epoch (1970-01-01 00:00:00 UTC)
%S
second as a decimal number [00..60].
%t
tab character.
%T
time (%H:%M:%S).
%u
weekday as a decimal number [1..7], with 1 representing Monday.
%U
week number of the year (Sunday as the first day of the week) as a decimal number [00..53].
%V
week number of the year (Monday as the first day of the week) as a decimal number [01..53]. If the week containing 1 January has four or more days in the new year, then it is considered week 1. Otherwise, it is the last week of the previous year, and the next week is week 1.
%w
weekday as a decimal number [0..6], with 0 representing Sunday.
%W
week number of the year (Monday as the first day of the week) as a decimal number [00..53]. All days in a new year preceding the first Monday are considered to be in week 0.
%x
locale's appropriate date representation.
%X
locale's appropriate time representation.
%y
year without century as a decimal number [00..99].
%Y
year with century as a decimal number.
%Z
timezone name or abbreviation, or by no bytes if no timezone information exists.
%%
is replaced by %.
var date = new Date(2013, 3, 8, 9, 2, 4);
strftime(date, '%Y-%m-%d'); // "2013-04-08"
strftime(date, '%R'); // "09:02"
strftime(date, '%Y-%m-%dT%H:%M:%S%z'); // "2013-04-08T09:02:04+0000"

You can also set a custom locale:

var ptBr = require('mout/date/i18n/pt-BR');
strftime(date, '%a, %d %b', ptBr); // 'Seg, 08 Abr'
strftime(date, '%A, %d %B', ptBr); // 'Segunda, 08 Abril'

To set it globally:

require('mout/date/i18n_').set( customLocaleData );

See date/i18n for localization examples.

timezoneAbbr(date):String

Return timezone abbreviation or similar data.

The result will vary based on the OS/browser since some environments doesn't provide enough info about the current locale.

// IE 7-8
timezoneAbbr(new Date()); // "-0500"
// Chrome, FF, V8
timezoneAbbr(new Date()); // "EST"

timezoneOffset(date):String

Return time zone as hour and minute offset from UTC (e.g. +0900).

It's important to note that JavaScript Date object will use the system locale info to determinate the timezone offset and that daylight saving time affects the result.

// if system locale is EST
timezoneOffset(new Date()); // -0500

totalDaysInMonth(fullYear, monthIndex):Number

Returns the amount of days in the month taking into consideration leap years (following Gregorian calendar).

see: isLeapYear()

totalDaysInMonth(2008, 1); // 29 (leap year)
totalDaysInMonth(2009, 1); // 28

// you can also pass a Date object as single argument
totalDaysInMonth( new Date(2013, 0, 1) ); // 31

totalDaysInYear(fullYear):Number

Returns the amount of days in the year taking into consideration leap years (following Gregorian calendar).

see: isLeapYear(), totalDaysInMonth()

totalDaysInYear(2008); // 366 (leap year)
totalDaysInYear(2009); // 365

// you can also pass a Date object as single argument
totalDaysInYear( new Date(2013, 0, 1) ); // 365

weekOfTheYear(date, [firstDayOfWeek]):Number

Returns how many weeks elapsed since start of the year (0..53).

firstDayOfWeek can be 0 (Sunday) or 1 (Monday). By default weeks start at Sunday.

It will return 0 if date is before the first firstDayOfWeek of the year.

// Tue Jan 01 2013
weekOfTheYear( new Date(2013,0,1) ); // 0
// Wed Jan 09 2013
weekOfTheYear( new Date(2013,0,9) ); // 1
// Sun Jan 01 2012
weekOfTheYear( new Date(2012,0,1) ); // 1
// Mon Jan 09 2012
weekOfTheYear( new Date(2012,0,9) ); // 2

For more usage examples check specs inside /tests folder. Unit tests are the best documentation you can get...

function

Function*(al)* utilities.

after(fn, n):Function

This creates a function that will only call fn if it was called n or more times.

function onLoaded() {
    console.log('all images loaded');
}

var imagePaths = ['1.jpg', '2.jpg', '3.jpg'];
var callback = after(onLoaded, imagePaths.length);

forEach(imagePaths, function(path) {
    asyncLoad(path, callback);
});

awaitDelay(fn, delay):Function

Returns a function that ensures that fn is only called after delay milliseconds have elapsed. When the returned function is called before the delay has elapsed, it will wait until the delay has elapsed and then call fn. When the returned function is called after the delay has elapsed, it will call fn after the next "tick" (it will always be called asynchronously). The context and arguments that the returned function is called in are applied to fn.

In the below example onLoaded will not be executed before a 1000 millisecond delay. Even if loadImages loads and calls callback earlier. However, say the images take 1500 milliseconds to load, it will trigger onLoaded immediately.

var callback = awaitDelay(onLoaded, 1000);
loadImages(callback);
function onLoaded(){
    console.log('loaded');
}

You can also cancel de delayed call by simply using the native clearTimeout method (like a regular setTimeout call).

var timeoutId = callback();
// onLoaded won't be called since it was canceled before the 1000ms delay
clearTimeout(timeoutId);

Arguments:

  1. fn (Function) : Target Function
  2. delay (Number) : Delay of execution in milliseconds

See: debounce()

bind(fn, context, [...args]):Function

Return a function that will execute in the given context, optionally adding any additional supplied parameters to the beginning of the arguments collection.

Arguments

  1. fn (Function) : Target Function
  2. context (Object) : Execution context (object used as this)
  3. [...args] (*) : Arguments (0...n arguments)

See: partial(), object/bindAll

compose(...fn):Function

Returns the composition of a list of functions, where each function consumes the return value of the function that follows. In math terms, composing the functions f(), g(), and h() produces f(g(h())).

function add2(x) { return x + 2 }
function multi2(x) { return x * 2 }
map([1, 2, 3], compose(add2, multi2)); // [4, 6, 8]

//same as
map([1, 2, 3], function(x){
    return add2( multi2(x) );
});

constant(value):Function

Returns a new function that will always return value when called.

var f = constant('foo');
f(); // 'foo'

// Provided arguments are ignored; value is always returned
f(1); // 'foo'

f = constant({ foo: 'bar' });
f(); // { foo: 'bar' }

debounce(fn, delay[, isAsap]):Function

Creates a function that will delay the execution of fn until after delay milliseconds have elapsed since the last time it was invoked.

Subsequent calls to the debounced function will return the result of the last fn call.

// sometimes less is more
var lazyRedraw = debounce(redraw, 300);
foo.on.resize.add(lazyRedraw);

In this visualization, | is a debounced-function call and X is the actual callback execution:

Default
||||||||||||||||||||||||| (pause) |||||||||||||||||||||||||
                         X                                 X

Debounced with `isAsap == true`:
||||||||||||||||||||||||| (pause) |||||||||||||||||||||||||
X                                 X

You also have the option to cancel the debounced call if it didn't happen yet:

lazyRedraw();
// lazyRedraw won't be called since `cancel` was called before the `delay`
lazyRedraw.cancel();

See: throttle()

func(name):Function

Returns a function that calls a method with given name on supplied object. Useful for iteration methods like array/map and array/forEach.

See: prop()

// will call the method `getName()` for each `user`
var names = map(users, func('getName'));

identity(val):*

Returns the first argument provided to it.

identity(3);     // 3
identity(1,2,3); // 1
identity('foo'); // "foo"

partial(fn, [...args]):Function

Return a partially applied function supplying default arguments.

This method is similar to bind, except it does not alter the this binding.

Arguments

  1. fn (Function) : Target Function
  2. [...args] (*) : Arguments (0...n arguments)

See: bind()

function add(a, b){ return a + b }
var add10 = partial(add, 10);
console.log( add10(2) ); // 12

prop(name):Function

Returns a function that gets a property with given name from supplied object. Useful for using in conjunction with array/map and/or for creating getters.

See: array/pluck()

var users = [{name:"John", age:21}, {name:"Jane", age:25}];
// ["John", "Jane"]
var names = map(users, prop('name'));

series(...fn):Function

Returns a function that will execute all the supplied functions in order and passing the same parameters to all of them. Useful for combining multiple array/forEach into a single one and/or for debugging.

// call `console.log()` and `doStuff()` for each item item in the array
forEach(arr, series(console.log, doStuff));

throttle(fn, interval):Function

Creates a function that, when executed, will only call the fn function at most once per every interval milliseconds.

If the throttled function is invoked more than once during the wait timeout, fn will also be called on the trailing edge of the timeout.

Subsequent calls to the throttled function will return the result of the last fn call.

// sometimes less is more
var lazyRedraw = throttle(redraw, 300);
foo.on.resize.add(lazyRedraw);

In this visualization, | is a throttled-function call and X is the actual fn execution:

||||||||||||||||||||||||| (pause) |||||||||||||||||||||||||
X    X    X    X    X    X        X    X    X    X    X    X

You also have the option to cancel the throttled call if it didn't happen yet:

lazyRedraw();
setTimeout(function(){
    lazyRedraw();
    // lazyRedraw will be called only once since `cancel` was called before
    // the `interval` for 2nd call completed
    lazyRedraw.cancel();
}, 250);

See: debounce()

timeout(fn, millis, context, [...args]):Number

Functions as a wrapper for setTimeout. Calls a the function fn after a given delay millis in milliseconds. The function is called within the specified context. The return value can be used to clear the timeout using clearTimeout.

var id = timeout(doStuff, 300, this);

clearTimeout(id);

times(n, callback, [context]):void

Iterates over a callback n times.

Arguments

  1. n (Number) : Number of iterations
  2. callback (Function) : Closure executed for every iteration
  3. context (Object) : Execution context (object used as this)
var output = '';
times(5, function(i) {
    output += i.toString();
});
// output: 01234

wrap(fn, wrapper):Function

Wraps the first fn inside of the wrapper function, passing it as the first argument. This allows the wrapper to execute code before and after the fn runs, adjust the arguments, and execute it conditionally.

var hello = function(name) { return "hello: " + name; };
hello = wrap(hello, function(func) {
  return "before, " + func("moe") + ", after";
});
hello();
// output: 'before, hello: moe, after'

For more usage examples check specs inside /tests folder. Unit tests are the best documentation you can get...

lang

Language Utilities. Easier inheritance, scope handling, type checks.

clone(val):*

Clone native types like Object, Array, RegExp, Date and primitives.

This method will not clone values that are referenced within val. It will only copy the value reference to the new value. If the value is not a plain object but is an object, it will return the value unchanged.

Example

var a = { foo: 'bar' };
var b = clone(a);
console.log(a === b); // false
console.log(a.foo === b.foo); // true

var c = [1, 2, 3];
var d = clone(b);
console.log(c === d); // false
console.log(c); // [1, 2, 3]

See: deepClone()

createObject(parent, [props]):Object

Create Object using prototypal inheritance and setting custom properties.

Mix between Douglas Crockford Prototypal Inheritance and object/mixIn.

Arguments

  1. parent (Object) : Parent Object
  2. [props] (Object) : Object properties

Example

var base = {
    trace : function(){
        console.log(this.name);
    }
};

var myObject = createObject(base, {
    name : 'Lorem Ipsum'
});

myObject.trace(); // "Lorem Ipsum"

ctorApply(constructor, args):Object

Do Function.prototype.apply() on a constructor while maintaining prototype chain.

function Person(name, surname) {
    this.name = name;
    this.surname = surname;
}

Person.prototype.walk = function(){
    console.log(this.name +' is walking');
};

var args = ['John', 'Doe'];

// "similar" effect as calling `new Person("John", "Doe")`
var john = ctorApply(Person, args);
john.walk(); // "John is walking"

deepClone(val, [instanceClone]):*

Deep clone native types like Object, Array, RegExp, Date and primitives.

The instanceClone function will be invoked to clone objects that are not "plain" objects (as defined by isPlainObject) if it is provided. If instanceClone is not specified, it will not attempt to clone non-plain objects, and will copy the object reference.

Example

var a = {foo:'bar', obj: {a:1, b:2}};
var b = deepClone(a); // {foo:'bar', obj: {a:1, b:2}}
console.log( a === b ); // false
console.log( a.obj === b.obj ); // false

var c = [1, 2, [3, 4]];
var d = deepClone(c); // [1, 2, [3, 4]]
var e = c.concat(); // [1, 2, [3, 4]]

console.log( c[2] === d[2] ); // false
// concat doesn't do a deep clone, arrays are passed by reference
console.log( e[2] === d[2] ); // true

function Custom() { }
function cloneCustom(x) { return new Custom(); }
var f = { test: new Custom() };
var g = deepClone(f, cloneCustom);
g.test === f.test // false, since new Custom instance will be created

See: clone()

deepEquals(a, b, [callback]):Boolean

Recursively tests whether two values contains the same keys and values.

callback specifies the equality comparison function used to compare non-object values. It defaults to using the is() function.

If the values are both an object or array, it will recurse into both values, checking if their keys/values are equal. It will only check the keys and values contained by the objects; it will not check the objects' prototypes. If either of the values are not objects, they will be checked using the callback function.

Example:

deepEquals({ a: 1 }, { a: 1 }); // true
deepEquals({ value: { a: 1 } }, { value: { a: 1 } }); // true
deepEquals({ value: { a: 1 } }, { value: { a: 2 } }); // false
deepEquals({ value: { a: 1 } }, { value: { a: 1, b: 2 } }); // false
deepEquals({}, null); // false
deepEquals(null, null); // true
deepEquals(
    { a: { b: 1 } },
    { a: { b: '1' } },
    function(a, b) { return a == b; }); // true

See: object/equals, array/equals

defaults(val, ...defaults):void

Return first value that isn't null or undefined.

function doSomethingAwesome(foo, bar) {
    // default arguments
    foo = defaults(foo, 'lorem');
    bar = defaults(bar, 123);
    // ...
}

GLOBAL:Object

Reference to the global context (window inside a browser, global on node.js). Works on ES3 and ES5 strict-mode.

inheritPrototype(childCtor, parentCtor):Object

Inherit the prototype methods from one constructor into another.

Similar to node.js util/inherits.

It returns the the childCtor.prototype for convenience.

function Foo(name){
    this.name = name;
}
Foo.prototype = {
    getName : function(){
        return this.name;
    }
};

function Bar(name){
    Foo.call(this, name);
}
//should be called before calling constructor
var proto = inheritPrototype(Bar, Foo);

// for convenience we return the new prototype object
console.log(proto === Bar.prototype); // true

var myObj = new Bar('lorem ipsum');
myObj.getName(); // "lorem ipsum"

console.log(myObj instanceof Foo); // true

// you also have access to the "super" constructor
console.log(Bar.super_ === Foo); // true

is(x, y):Boolean

Check if both values are identical/egal.

// wtfjs
NaN === NaN; // false
-0 === +0;   // true

is(NaN, NaN); // true
is(-0, +0);   // false
is('a', 'b'); // false

See: isnt()

isnt(x, y):Boolean

Check if both values are not identical/egal.

// wtfjs
NaN === NaN; // false
-0 === +0;   // true

isnt(NaN, NaN); // false
isnt(-0, +0);   // true
isnt('a', 'b'); // true

See: is()

isArguments(val):Boolean

If value is an "Arguments" object.

isArray(val):Boolean

If value is an Array. Uses native ES5 Array.isArray() if available.

isBoolean(val):Boolean

If value is a Boolean.

isDate(val):Boolean

If value is a Date.

isEmpty(val):Boolean

Checks if Array/Object/String is empty.

Will return true for any object that doesn't contain enumerable properties and also to any type of value that isn't considered a collection (boolean, null, undefined, function, etc).

isEmpty('');         // true
isEmpty('bar');      // false
isEmpty([]);         // true
isEmpty([1, 2]);     // false
isEmpty({});         // true
isEmpty({a:1, b:2}); // false
// null, undefined, booleans, numbers are considered as "empty" values
isEmpty(null);       // true
isEmpty(undefined);  // true
isEmpty(123);        // true
isEmpty(true);       // true

isFinite(val):Boolean

Checks if value is Finite.

IMPORTANT: This is not the same as native isFinite, which will return true for values that can be coerced into finite numbers. See http://es5.github.com/#x15.1.2.5.

isFinite(123);      // true
isFinite(Infinity); // false

// this is different than native behavior
isFinite('');   // false
isFinite(true); // false
isFinite([]);   // false
isFinite(null); // false

isFunction(val):Boolean

If value is a Function.

isKind(val, kind):Boolean

If value is of "kind". (used internally by some of the isSomething checks).

Favor the other methods since strings are commonly mistyped and also because some "kinds" can only be accurately checked by using other methods (e.g. Arguments), some of the other checks are also faster.

isKind([1,2], 'Array'); // true
isKind(3, 'Array');     // false
isKind(3, 'Number');    // true

See: kindOf()

isInteger(val):Boolean

Check if value is an integer.

isInteger(123);    // true
isInteger(123.45); // false
isInteger({});     // false
isInteger('foo');  // false
isInteger('123');  // false

isNaN(val):Boolean

Check if value is not a number.

It doesn't coerce value into number before doing the check, giving better results than native isNaN. Returns true for everything besides numeric values.

IMPORTANT: behavior is very different than the native isNaN and way more useful!!! See: http://es5.github.io/#x15.1.2.4

isNaN(123);       // false

isNaN(NaN);       // true
isNaN({});        // true
isNaN(undefined); // true
isNaN([4,5]);     // true

// these are all "false" on native isNaN and main reason why this module exists
isNaN('');    // true
isNaN(null);  // true
isNaN(true);  // true
isNaN(false); // true
isNaN("123"); // true
isNaN([]);    // true
isNaN([5]);   // true

isNull(val):Boolean

If value is null.

isNumber(val):Boolean

If value is a Number.

isObject(val):Boolean

If value is an Object.

isPlainObject(val):Boolean

If the value is an Object created by the Object constructor.

isRegExp(val):Boolean

If value is a RegExp.

isString(val):Boolean

If value is a String.

isUndefined(val):Boolean

If value is undefined.

kindOf(val):String

Gets kind of value (e.g. "String", "Number", "RegExp", "Null", "Date"). Used internally by isKind() and most of the other isSomething checks.

kindOf([1,2]); // "Array"
kindOf('foo'); // "String"
kindOf(3);     // "Number"

See: isKind()

toArray(val):Array

Convert array-like object into Array or wrap value into Array.

toArray({
    "0" : "foo",
    "1" : "bar",
    "length" : 2
});                              // ["foo", "bar"]

function foo(){
    return toArray(arguments);
}
foo("lorem", 123);               // ["lorem", 123]

toArray("lorem ipsum");          // ["lorem ipsum"]
toArray(window);                 // [window]
toArray({foo:"bar", lorem:123}); // [{foo:"bar", lorem:123}]

See: object/values()

toNumber(val):Number

Convert value into number.

// numeric values are typecasted as Number
toNumber('123');     // 123
toNumber(-567);      // -567

// falsy values returns zero
toNumber('');        // 0
toNumber(null);      // 0
toNumber(undefined); // 0
toNumber(false);     // 0

// non-numeric values returns NaN
toNumber('asd');     // NaN
toNumber({});        // NaN
toNumber([]);        // NaN

// Date objects return milliseconds since epoch
toNumber(new Date(1985, 6, 23)); // 490935600000

toString(val):String

Convert any value to its string representation.

Will return an empty string for undefined or null, otherwise will convert the value to its string representation.

// null and undefined are converted into empty strings
toString(null);      // ""
toString(undefined); // ""

toString(1);       // "1"
toString([1,2,3]); // "1,2,3"
toString(false);   // "false"

// uses `val.toString()` to convert value
toString({toString:funtion(){ return 'foo'; }}); // "foo"

For more usage examples check specs inside /tests folder. Unit tests are the best documentation you can get...

math

Math utilities.

ceil(val[, step]):Number

Round value up to full steps. Similar to Math.ceil() but can round value to an arbitrary radix.

ceil(7.2);   // 8
ceil(7.8);   // 8
ceil(7, 5);  // 10
ceil(11, 5); // 15
ceil(15, 5); // 15

Common use cases

Round values by increments of 5/10/1000/etc.

See: round(), floor(), countSteps()

clamp(val, min, max):Number

Clamps value inside range.

clamp() is extremely useful in cases where you need to limit a value inside a certain range. So instead of doing a complex if/else to filter/process the value you can restrict it to always be inside the desired range:

clamp(-5, 0, 10); // 0
clamp(7, 1, 10);  // 7
clamp(8, 1, 10);  // 8
clamp(10, 1, 10); // 10
clamp(11, 1, 10); // 10

If the value is smaller than min it returns the min, if val is higher than max it returns max.

Common use cases

Any situation where you need to limit a number inside a range like: slider position, image galleries (so user can't skip to an image that doesn't exist), drag and drop, scroll boundaries, etc.

See: loop()

countSteps(val, step[, overflow]):Number

Count number of full steps.

Arguments:

  1. val (Number) : Value.
  2. step (Number) : Step size.
  3. [overflow] (Number) : Maximum number of steps, nSteps will loop if >= than overflow.

Count steps is very useful for cases where you need to know how many "full steps" the number completed. Think of it as a division that only returns integers and ignore remainders.

countSteps(3,  5);    // 0
countSteps(6,  5);    // 1
countSteps(12, 5);    // 2
countSteps(18, 5);    // 3
countSteps(21, 5);    // 4

You can also set an overflow which will reset the counter before reaching this number.

countSteps(3, 5, 3);  // 0
countSteps(6, 5, 3);  // 1
countSteps(12, 5, 3); // 2
countSteps(18, 5, 3); // 0
countSteps(21, 5, 3); // 1

Common use cases

How many items fit inside an area:

var containerWidth = 100;
var itemWidth = 8;
var howManyFit = countSteps(containerWidth, itemWidth); // 12

Split value into different scales or convert value from one scale to another

From mout/time/parseMs:

function parseMs(ms){
    return {
        milliseconds : countSteps(ms, 1, 1000),
        seconds      : countSteps(ms, 1000, 60),
        minutes      : countSteps(ms, 60000, 60),
        hours        : countSteps(ms, 3600000, 24),
        days         : countSteps(ms, 86400000)
    };
}

// {days:27, hours:4, minutes:26, seconds:5, milliseconds:454}
parseMs(2348765454);

floor(val[, step]):Number

Round value down to full steps. Similar to Math.floor() but can round value to an arbitrary radix. (formerly snap)

floor(7.2);   // 7
floor(7.8);   // 7
floor(7, 5);  // 5
floor(11, 5); // 10
floor(15, 5); // 15

Common use cases

Round values by increments of 5/10/1000/etc.

See: round(), ceil(), countSteps()

inRange(val, min, max[, threshold]):Boolean

Checks if value is inside the range.

inRange(-6, 1, 10);    // false
inRange( 5, 1, 10);    // true
inRange(12, 1, 10);    // false

The threshold can be useful when you want granular control of what should match and/or the precision could change at runtime or by some configuration option, avoids the clutter of adding/subtracting the threshold from mix and max.

inRange(12, 1, 10, 2); // true
inRange(13, 1, 10, 2); // false

Common use cases

Anything that needs to check if value is inside a range, be it collision detection, limiting interaction by mouse position, ignoring parts of the logic that shouldn't happen if value isn't valid, simplify if/else conditions, making code more readable, etc...

isNear(val, target, threshold):Boolean

Check if value is close to target.

Similar to inRange() but used to check if value is close to a certain value or match the desired value. Basically to simplify if/else conditions and to make code clearer.

isNear( 10.2, 10, 0.5); // true
isNear( 10.5, 10, 0.5); // true
isNear(10.51, 10, 0.5); // false

Common use cases

Games where a certain action should happen if an actor is close to a target, gravity fields, any numeric check that has some tolerance.

lerp(ratio, start, end):Number

Linear interpolation.

lerp(0.5, 0, 10);  // 5
lerp(0.75, 0, 10); // 7.5

Common use cases

Linear interpolation is commonly used to create animations of elements moving from one point to another, where you simply update the current ratio (which in this case represents time) and get back the position of the element at that "frame".

The core idea of lerp is that you are using a number that goes from 0 to 1 to specify a ratio inside that scale. This concept can be applied to convert numbers from different scales easily.

See: map(), norm()

loop(val, min, max):Number

Loops value inside range. Will return min if val > max and max if val < min, otherwise it returns val.

loop(-1, 0, 10); // 10
loop( 1, 0, 10); // 1
loop( 5, 0, 10); // 5
loop( 9, 0, 10); // 9
loop(10, 0, 10); // 10
loop(11, 0, 10); // 0

Similar to clamp() but loops the value inside the range when an overflow occurs.

Common use cases

Image galleries, infinite scroll, any kind of logic that requires that the first item should be displayed after the last one or the last one should be displayed after first if going on the opposite direction.

See: clamp()

map(val, min1, max1, min2, max2):Number

Maps a number from one scale to another.

map(3, 0, 4, -1, 1)   // 0.5
map(3, 0, 10, 0, 100) // 30

Common use cases

Very useful to convert values from/to multiple scales.

Let's suppose we have a slider that needs to go from 2000 to 5000 and that slider has 300px of width, here is how we would translate the knob position into the current value:

var knobX = 123;
var sliderWid = 300;
var minVal = 2000;
var maxVal = 5000;

var curVal = map(knobX, 0, sliderWid, minVal, maxVal); // 3230

See: lerp(), norm()

norm(val, min, max):Number

Gets normalized ratio of value inside range.

If val < min or val > max it will throw a RangeError since we can't normalize the value.

norm(50, 0, 100); // 0.5
norm(75, 0, 100); // 0.75
norm(100, 0, 100); // 1
norm(-50, 0, 100); // RangeError: value (-50) must be between 0 and 100

Common use cases

Convert values between scales, used by map() internally. Direct opposite of lerp().

See: lerp(), map()

overflow(val[, min], max):Number

Wraps number within [min, max). When no min is given, the value 0 is assumed. A number larger or equal max loops around and starts over at min. For positive numbers larger or equal max this method behaves identical to the modulo operator. Numbers smaller than min loop around and start over at max.

overflow(13, 5, 10); // 8
overflow(3, 5, 10); // 8
overflow(23, 5); // 3
overflow(-10, -7, -1); // -4

See: loop()

round(val[, step]):Number

Round value to full steps. Similar to Math.round() but allow setting an arbitrary radix.

// default
round(0.22);      // 0
round(0.49);      // 0
round(0.51);      // 1

// custom radix
round(0.22, 0.5); // 0
round(0.49, 0.5); // 0.5
round(0.51, 0.5); // 0.5
round(0.74, 0.5); // 0.5
round(0.75, 0.5); // 1
round(1.24, 0.5); // 1
round(1.25, 0.5); // 1.5
round(1.74, 0.5); // 1.5

Common use cases

Round values by increments of 0.5/5/10/1000/etc.

See: floor(), ceil(), countSteps()


For more usage more info check the specs and source code.

number

Number utilities.

abbreviate(val[, nDecimalDigits, dictionary]):String

Abbreviate number to thousands (K), millions (M) or billions (B).

The default value for nDecimalDigits is 1.

Example

abbreviate(123456);     // "123.5K"
abbreviate(12345678);   // "12.3M"
abbreviate(1234567890); // "1.2B"

You can set the amount of decimal digits (default is 1):

abbreviate(543);    // "0.5K"
abbreviate(543, 1); // "0.5K"
abbreviate(543, 2); // "0.54K"
abbreviate(543, 3); // "0.543K"

You can customize the abbreviation by passing a custom "dictionary":

var _ptbrDict = {
    thousand: ' mil',
    million: ' Mi',
    billion: ' Bi'
};
function customAbbr(val) {
    return abbreviate(val, 1, _ptbrDict);
}

customAbbr(123456); // "123.5 mil"
customAbbr(12345678); // "12.3 Mi"
customAbbr(1234567890); // "1.2 Bi"

currencyFormat(val[, nDecimalDigits, decimalSeparator, thousandsSeparator]):String

Format a number as currency.

Example:

currencyFormat(1000);              // "1,000.00"
currencyFormat(1000, 1);           // "1,000.0"
currencyFormat(1000, 2, ',', '.'); // "1.000,00"

enforcePrecision(val, nDecimalDigits):Number

Enforce a specific amount of decimal digits and also fix floating point rounding issues.

Example:

enforcePrecision(0.615, 2); // 0.62
enforcePrecision(0.625, 2); // 0.63
//floating point rounding "error" (rounds to odd number)
+(0.615).toFixed(2);        // 0.61
+(0.625).toFixed(2);        // 0.63

isNaN(val):Boolean

ES6 Number.isNaN(), checks if supplied value is NaN.

// only returns `true` for `NaN`
isNaN(NaN);    // true
isNaN(0 / 0);  // true

// everything else is `false`
isNaN(true);   // false
isNaN(123);    // false
isNaN('asd');  // false
isNaN('NaN');  // false

MAX_INT:Number

Maximum 32-bit signed integer value. Math.pow(2, 31) - 1

Example:

console.log( MAX_INT ); // 2147483647

MAX_SAFE_INTEGER:Number

Maximum safe integer. Math.pow(2,53) − 1

MAX_UINT:Number

Maximum 32-bit unsigned integer value. Math.pow(2, 32) - 1

Example:

console.log( MAX_UINT ); // 4294967295

MIN_INT:Number

Minimum 32-bit signed integer value. Math.pow(2, 31) * -1.

Example:

console.log( MIN_INT ); // -2147483648

nth(n):String

Returns the "nth" of number. ("st", "nd", "rd", "th")

nth(1); // "st"
nth(2); // "nd"
nth(12); // "th"
nth(22); // "nd"
nth(23); // "rd"
nth(34); // "th"

See: ordinal()

ordinal(n):String

Converts number into ordinal form (1st, 2nd, 3rd, 4th, ...)

ordinal(1); // "1st"
ordinal(2); // "2nd"
ordinal(3); // "3rd"
ordinal(14); // "14th"
ordinal(21); // "21st"

See: nth()

pad(n, minLength[, char]):String

Add padding zeros if n.length < minLength.

Example:

pad(1, 5);      // "00001"
pad(12, 5);     // "00012"
pad(123, 5);    // "00123"
pad(1234, 5);   // "01234"
pad(12345, 5);  // "12345"
pad(123456, 5); // "123456"

// you can also specify the "char" used for padding
pad(12, 5, '_'); // "___12"

see: string/lpad

rol(val, shift):Number

Bitwise circular shift left.

More info at Wikipedia#Circular_shift

ror(val, shift):Number

Bitwise circular shift right.

More info at Wikipedia#Circular_shift

sign(val):Number

Returns -1 if value is negative, 0 if the value is 0 and 1 if value is positive. Useful for multiplications.

sign(-123); // -1
sign(123);  // 1
sign(0);    // 0

toInt(val):Number

"Convert" value into an 32-bit integer. Works like Math.floor if val > 0 and Math.ceil if val < 0.

IMPORTANT: val will wrap at number/MIN_INT and number/MAX_INT.

Created because most people don't know bitwise operations and also because this feature is commonly needed.

Perf tests

Example:

toInt(1.25);   // 1
toInt(0.75);   // 0
toInt(-0.55);  // 0
toInt(-5.0001) // -5

toUInt(val):Number

"Convert" value into an 32-bit unsigned integer.

Works like AS3#uint().

IMPORTANT: val will wrap at 2^32.

Example:

toUInt(1.25);                 // 1
toUInt(0.75);                 // 0
toUInt(-0.55);                // 0
toUInt(-5.0001);              // 4294967291
toUInt(Math.pow(2,32) - 0.5); // 4294967295
toUInt(Math.pow(2,32) + 0.5); // 0

toUInt31(val):Number

"Convert" value into an 31-bit unsigned integer (since 1 bit is used for sign).

Useful since all bitwise operators besides >>> treat numbers as signed integers.

IMPORTANT: val will wrap at 2^31 and negative numbers will be treated as zero.

Example:

toUInt31(1.25);                 // 1
toUInt31(0.75);                 // 0
toUInt31(-0.55);                // 0
toUInt31(-5.0001);              // 0
toUInt31(Math.pow(2,31) - 0.5); // 21474836470
toUInt31(Math.pow(2,31) + 0.5); // 0

For more usage examples check specs inside /tests folder. Unit tests are the best documentation you can get...

object

Object utilities.

bindAll(obj, [...methodNames]):void

Bind methods of the target object to always execute on its own context (ovewritting the original function).

See: function/bind

var view = {
    name: 'Lorem Ipsum',
    logNameOnClick: function() {
        console.log(this.name);
    }
};

// binds all methods by default
bindAll(view);
jQuery('#docs').on('click', view.logNameOnClick);

You can also specify the list of methods that you want to bind (in case you just want to bind a few of them).

// only the listed methods will be bound to `obj` context
bindAll(obj, 'logNameOnClick', 'doAwesomeStuffOnDrag');

contains(obj, value):Boolean

Similar to Array/contains. Checks if Object contains value.

var obj = {
    a: 1,
    b: 2,
    c: 'bar'
};
contains(obj, 2);      // true
contains(obj, 'foo');  // false

deepFillIn(target, ...objects):Object

Fill missing properties recursively.

It's different from deepMixIn since it won't override any existing property. It's also different from merge since it won't clone child objects during the process.

It returns the target object and mutates it in place.

See: fillIn(), deepMixIn(), merge()

var base = {
    foo : {
        bar : 123
    },
    lorem : 'ipsum'
};
var options = deepFillIn({foo : { baz : 45 }, lorem : 'amet'}, base);
// > {foo: {bar:123, baz : 45}, lorem : 'amet'}

deepMatches(target, pattern):Boolean

Recursively checks if object contains all properties/value pairs. When both the target and pattern values are arrays, it checks that the target value contain matches for all the items in the pattern array (independent of order).

var john = {
    name: 'John',
    age: 22,
    pets: [
        { type: 'cat', name: 'Grumpy Cat' },
        { type: 'dog', name: 'Hawk' }
    ]
};

deepMatches(john, { name: 'John' }); // true
deepMatches(john, { age: 21 }); // false
deepMatches(john, { pets: [ { type: 'cat' } ] }); // true
deepMatches(john, { pets: [ { name: 'Hawk' } ] }); // true
deepMatches(john, { pets: [ { name: 'Hairball' } ] }); // false

See matches()

deepMixIn(target, ...objects):Object

Mixes objects into the target object, recursively mixing existing child objects as well.

It will only recursively mix objects if both (existing and new) values are plain objects.

Returns the target object. Like merge(), but mutates the target object, and does not clone child objects.

var target = {
    foo: {
        name: "foo",
        id: 1
    }
};

deepMixIn(target, { foo: { id: 2 } });
console.log(target); // { foo: { name: "foo", id: 2 } }

See: mixIn(), merge(), deepFillIn()

equals(a, b, [callback]):Boolean

Tests whether two objects contain the same keys and values.

callback specifies the equality comparison function used to compare the values. It defaults to using lang/is.

It will only check the keys and values contained by the objects; it will not check the objects' prototypes. If either of the values are not objects, they will be compared using the callback function.

equals({}, {}); // true
equals({ a: 1 }, { a: 1 }); // true
equals({ a: 1 }, { a: 2 }); // false
equals({ a: 1, b: 2 }, { a: 1 }); // false
equals({ a: 1 }, { a: 1, b: 2 }); // false
equals(null, null); // true
equals(null, {}); // false
equals({ a: 1 }, { a: '1' }, function(a, b) { return a == b; }); // true

See: array/equals, lang/deepEquals

every(obj, callback, [thisObj]):Boolean

Similar to Array/every. Tests whether all properties in the object pass the test implemented by the provided callback.

var obj = {
    a: 1,
    b: 2,
    c: 3,
    d: 'string'
};

every(obj, isNumber); // false

fillIn(obj, ...default):Object

Fill in missing properties in object with values from the defaults objects.

var base = {
    foo : 'bar',
    num : 123
};

fillIn({foo:'ipsum'}, base); // {foo:'ipsum', num:123}

PS: it allows merging multiple objects at once, the first ones will take precedence.

See: mixIn(), merge(), deepFillIn()

filter(obj, callback, [thisObj])

Returns a new object containing all properties where callback returns true, similar to Array/filter. It does not use properties from the object's prototype.

Callback receives the same arguments as forOwn().

See: forOwn(), forIn(), pick()

var obj = {
    foo: 'value',
    bar: 'bar value'
};

// returns { bar: 'bar value' }
filter(obj, function(v) { return v.length > 5; });

// returns { foo: 'value' }
filter(obj, function(v, k) { return k === 'foo'; });

find(obj, callback, [thisObj])

Loops through all the properties in the Object and returns the first one that passes a truth test (callback), similar to Array/find. Unlike Array/find, order of iteration is not guaranteed.

var obj = {
    a: 'foo',
    b: 12
};

find(obj, isString); // 'foo'
find(obj, isNumber); // 12

flatten(object, [level]):Object

Recursively flattens an object. A new object containing all the values is returned. If level is specified, it will only flatten up to that level. Note that objects within arrays will not be flattened.

Example

flatten({ a: 1, b: { c: 2, d: { e: 3 } } });
// > { a: 1, 'b.c': 2, 'b.d.e': 3 }
flatten({ a: 1, b: { c: 2, d: { e: 3 } } }, 1);
// > { a: 1, 'b.c': 2, 'b.d': { e: 3 } }

See: array/flatten()

forIn(obj, callback[, thisObj])

Iterate over all properties of an Object, similar to Array/forEach.

It avoids don't enum bug on IE. It will iterate over inherited (enumerable) properties from the prototype.

It allows exiting the iteration early by returning false on the callback.

See: forOwn(), keys(), values()

Callback arguments

Callback will receive the following arguments:

  1. Property Value (*)
  2. Key name (String)
  3. Target object (Object)

Example

function Foo(){
    this.foo = 1;
    this.bar = 2;
}

Foo.prototype.lorem = 4;

var obj = new Foo();

var result = 0;
var keys = [];

forIn(obj, function(val, key, o){
    result += val;
    keys.push(key);
});

console.log(result); // 7
console.log(keys);   // ['foo', 'bar', 'lorem']

forOwn(obj, callback[, thisObj])

Iterate over all own properties from an Object, similar to Array/forEach.

It avoids don't enum bug on IE. Notice that it won't iterate over properties from the prototype.

It allows exiting the iteration early by returning false on the callback.

See: forIn(), keys(), values()

Callback arguments

Callback will receive the following arguments:

  1. Property Value (*)
  2. Key name (String)
  3. Target object (Object)

Example

function Foo(){
    this.foo = 1;
    this.bar = 2;
}

// will be ignored
Foo.prototype.lorem = 4;

var obj = new Foo();

var result = 0;
var keys = [];

forOwn(obj, function(val, key, o){
    result += val;
    keys.push(key);
});

console.log(result); // 3
console.log(keys);   // ['foo', 'bar']

functions(obj):Array

Returns a sorted list of all enumerable properties that have function values (including inherited properties).

var obj = {
    foo : function(){},
    bar : 'baz'
};
functions(obj); // ['foo']

get(obj, propName):*

Returns nested property value. Will return undefined if property doesn't exist or if the object is null or undefined.

See: set(), namespace(), has()

var lorem = {
        ipsum : {
            dolor : {
                sit : 'amet'
            }
        }
    };

get(lorem, 'ipsum.dolor.sit'); // "amet"
get(lorem, 'foo.bar');         // undefined
get(undefined, 'foo.bar');     // undefined

has(obj, propName):Boolean

Checks if object contains a child property. Useful for cases where you need to check if an object contain a nested property. It will get properties inherited by the prototype.

see: hasOwn(), get()

var a = {
        b : {
            c : 123
        }
    };

has(a, 'b.c');   // true
has(a, 'foo.c'); // false

Common use case

if( has(a, 'foo.c') ){ // false
    // ...
}

if( a.foo.c ){ // ReferenceError: `foo` is not defined
    // ...
}

hasOwn(obj, propName):Boolean

Safer Object.hasOwnProperty. Returns a boolean indicating whether the object has the specified property.

see: has()

var obj = {
    foo: 1,
    hasOwnProperty : 'bar'
};

obj.hasOwnProperty('foo'); // ERROR! hasOwnProperty is not a function

hasOwn(obj, 'foo');            // true
hasOwn(obj, 'hasOwnProperty'); // true
hasOwn(obj, 'toString');       // false

keys(obj):Array

Returns an array of all own enumerable properties found upon a given object. It will use the native Object.keys if present.

PS: it won't return properties from the prototype.

See: forOwn(), values()

var obj = {
    foo : 1,
    bar : 2,
    lorem : 3
};
keys(obj); // ['foo', 'bar', 'lorem']

map(obj, callback, [thisObj]):Object

Returns a new object where the property values are the result of calling the callback for each property in the original object, similar to Array/map.

The callback function receives the same arguments as in forOwn().

See: forOwn()

var obj = { foo: 1, bar: 2 },
    data = { foo: 0, bar: 1 };

map(obj, function(v) { return v + 1; }); // { foo: 2, bar: 3 }
map(obj, function(v, k) { return k; }); // { foo: "foo", bar: "bar" }
map(obj, function(v, k) { return this[k]; }, data); // { foo: 0, bar: 1 }

matches(obj, props):Boolean

Checks if object contains all properties/values pairs. Useful for validation and filtering.

var john = {age:25, hair:'long', beard:true};
var mark = {age:27, hair:'short', beard:false};
var hippie = {hair:'long', beard:true};
matches(john, hippie); // true
matches(mark, hippie); // false

See deepMatches()

merge(...objects):Object

Deep merges objects. Note that objects and properties will be cloned during the process to avoid undesired side effects. It return a new object and won't affect source objects.

var obj1 = {a: {b: 1, c: 1, d: {e: 1, f: 1}}};
var obj2 = {a: {b: 2, d : {f : 'yeah'} }};

merge(obj1, obj2); // {a: {b : 2, c : 1, d : {e : 1, f : 'yeah'}}}

See: deepMixIn(), deepFillIn()

max(obj[, iterator]):*

Returns maximum value inside object or use a custom iterator to define how items should be compared. Similar to Array/max.

See: min()

max({a: 100, b: 2, c: 1, d: 3, e: 200}); // 200
max({a: 'foo', b: 'lorem', c: 'amet'}, function(val){
    return val.length;
}); // 'lorem'

min(obj[, iterator]):*

Returns minimum value inside object or use a custom iterator to define how items should be compared. Similar to Array/min.

See: max()

min({a: 100, b: 2, c: 1, d: 3, e: 200}); // 1
min({a: 'foo', b: 'lorem', c: 'amet'}, function(val){
    return val.length;
}); // 'foo'

mixIn(target, ...objects):Object

Combine properties from all the objects into first one.

This method affects target object in place, if you want to create a new Object pass an empty object as first parameter.

Arguments

  1. target (Object) : Target Object.
  2. ...objects (...Object) : Objects to be combined (0...n objects).

Example

var a = {foo: "bar"};
var b = {lorem: 123};

mixIn({}, a, b); // {foo: "bar", lorem: 123}
console.log(a);  // {foo: "bar"}

mixIn(a, b);     // {foo: "bar", lorem: 123}
console.log(a);  // {foo: "bar", lorem: 123}

See: fillIn(), merge()

namespace(obj, propName):Object

Creates an empty object inside namespace if not existent. Will return created object or existing object.

See: get(), set()

var obj = {};
namespace(obj, 'foo.bar'); // {}
console.log(obj);          // {foo:{bar:{}}}

omit(obj, ...keys):Object

Return a copy of the object without the blacklisted keys.

See: filter()

var user = {
    firstName : 'John',
    lastName : 'Doe',
    dob : '1985/07/23',
    gender : 'male'
};

// can pass an array of keys as second argument
var keys = ['firstName', 'dob']
omit(user, keys); // {lastName : 'Doe', gender : 'male'}

// or multiple arguments
omit(user, 'firstName', 'lastName'); // {dob : '1985/07/23', gender : 'male'}

pick(obj, ...keys):Object

Return a copy of the object that contains only the whitelisted keys.

See: filter()

var user = {
    firstName : 'John',
    lastName : 'Doe',
    dob : '1985/07/23',
    gender : 'male'
};

// can pass an array of keys as second argument
var keys = ['firstName', 'dob']
pick(user, keys); // {firstName:"John", dob: "1985/07/23"}

// or multiple arguments
pick(user, 'firstName', 'lastName'); // {firstName:"John", lastName: "Doe"}

pluck(obj, propName):Object

Extract an object containing property values with keys as they appear in the passed object.

var users = {
    first: {
        name : 'John',
        age : 21
    },
    second: {
        name : 'Mary',
        age : 25
    }
};

pluck(users, 'name'); // {first: 'John', second: 'Mary'} );
pluck(users, 'age');  // {first: 21, second: 25} );

reduce(obj, callback, initial, [thisObj]):*

Similar to Array/reduce.

Apply a function against an accumulator and each property of the object (order is undefined) as to reduce it to a single value.

var obj = {a: 1, b: 2, c: 3, d: 4};

function sum(prev, cur, key, list) {
    compare1.push(prev);
    return prev + cur;
}

reduce(obj, sum); // 10

reject(obj, callback, thisObj):Object

Returns a new object containing all properties where callback returns true, similar to Array/reject. It does not use properties from the object's prototype. Opposite of filter().

See filter()

Example

var obj = {a: 1, b: 2, c: 3, d: 4, e: 5};
reject(obj, function(x) { return (x % 2) !== 0; }); // {b: 2, d: 4}

values(obj):Array

Returns an array of all own enumerable properties values found upon a given object.

PS: it won't return properties from the prototype.

See: forOwn(), keys()

var obj = {
    foo : 1,
    bar : 2,
    lorem : 3
};
values(obj); // [1, 2, 3]

set(obj, propName, value)

Sets a nested property value.

See: get(), namespace()

var obj = {};
set(obj, 'foo.bar', 123);
console.log(obj.foo.bar); // 123
console.log(obj);         // {foo:{bar:123}}

size(obj):Number

Returns the count of own enumerable properties found upon a given object.

PS: it won't return properties from the prototype.

See: forOwn(), keys()

var obj = {
    foo : 1,
    bar : 2,
    lorem : 3
};
size(obj); // 3

some(obj, callback, [thisObj]):Boolean

Similar to Array/some. Tests whether any properties in the object pass the test implemented by the provided callback.

var obj = {
    a: 1,
    b: 2,
    c: 3,
    d: 'string'
};

some(obj, isNumber); // true

unset(obj, propName):Boolean

Delete object property if existent and returns a boolean indicating succes. It will also return true if property doesn't exist.

Some properties can't be deleted, to understand why check this article.

See: set()

var lorem = {
        ipsum : {
            dolor : {
                sit : 'amet'
            }
        }
    };

unset(lorem, 'ipsum.dolor.sit'); // true
console.log(lorem.ipsum.dolor);  // {}
unset(lorem, 'foo.bar');         // true

result(object, property):Mixed

Evaluates an objects property and returns result.

var person = {
    name: 'john',

    mood: function() {
        // some dynamic calculated property.
        return 'happy';
    }
};

var name = result(person, 'name'), // john
    mood = result(person, 'mood'); // happy

queryString

Utilities for query string manipulation.

contains(url, paramName):Boolen

Checks if query string contains parameter.

Arguments:

  1. url (String) : URL or query string.
  2. paramName (String) : Parameter name.

Example:

var url = 'example.com/?lorem=ipsum';
contains(url, 'lorem'); // true
contains(url, 'foo');   //false

decode(queryStr[, shouldTypecast]):Object

Parses query string and creates an object of keys => vals.

Will typecast value with string/typecast by default and decode string parameters using decodeURIComponent().

var query = '?foo=bar&lorem=123';
decode(query);        // {foo: "bar", lorem: 123}
decode(query, false); // {foo: "bar", lorem: "123"}

encode(obj):String

Encode object into a query string.

Will encode parameters with encodeURIComponent().

encode({foo: "bar", lorem: 123}); // "?foo=bar&lorem=123"

getParam(url, param[, shouldTypecast]):*

Get query parameter value.

Will typecast value with string/typecast by default.

See: setParam()

Arguments:

  1. url (String) : Url.
  2. param (String) : Parameter name.
  3. [shouldTypecast] (Boolean) : If it should typecast value.

Example:

var url = 'example.com/?foo=bar&lorem=123&ipsum=false';
getParam(url, 'dolor');        // "amet"
getParam(url, 'lorem');        // 123
getParam(url, 'lorem', false); // "123"

parse(url[, shouldTypecast]):Object

Parses URL, extracts query string and decodes it.

It will typecast all properties of the query object unless second argument is false.

Alias to: decode(getQuery(url)).

var url = 'example.com/?lorem=ipsum&a=123';
parse(url);        // {lorem: "ipsum", a: 123}
parse(url, false); // {lorem: "ipsum", a: "123"}

getQuery(url):String

Gets full query as string with all special chars decoded.

getQuery('example.com/?lorem=ipsum'); // "?lorem=ipsum"

setParam(url, paramName, value):String

Add new query string parameter to URL or update existing value.

See: getParam()

setParam('?foo=bar&lorem=0', 'lorem', 'ipsum'); // '?foo=bar&lorem=ipsum'
setParam('?lorem=1', 'foo', 123); // '?lorem=1&foo=123'

For more usage examples check specs inside /tests folder. Unit tests are the best documentation you can get...

random

Pseudo-random generators.

mout uses Math.random by default on all the pseudo-random generators, if you need a seeded random or a better algorithm see the random() documentation for instructions.

choice(...items):*

Returns a random element from the supplied arguments or from an array if single argument is an array.

Example:

choice(1, 2, 3, 4, 5); // 3

var arr = ['lorem', 'ipsum', 'dolor'];
choice(arr); // 'dolor'

guid():String

Generates a pseudo-random Globally Unique Identifier (v4).

Since the total number of GUIDs is 2122 the chance of generating the same value twice is negligible.

Important: this method uses Math.random by default so the UUID isn't safe (sequence of outputs can be predicted in some cases), check the random() documentation for more info on how to replace the default PRNG if you need extra safety or need seeded results.

See: randHex(), random()

Example:

guid();      // 830e9f50-ac7f-4369-a14f-ed0e62b2fa0b
guid();      // 5de3d09b-e79c-4727-932b-48c49228d508

rand([min], [max]):Number

Gets a random number inside range or snap to min/max values.

Arguments:

  1. [min] (Number) : Minimum value. Defaults to number/MIN_INT.
  2. [max] (Number) : Maximum value. Defaults to number/MAX_INT.

Example:

rand();      // 448740433.55274725
rand();      // -31797596.097682
rand(0, 10); // 7.369723
rand(0, 10); // 5.987042

See: random()

randBit():Number

Returns a random "bit" (0 or 1). Useful for addition/subtraction.

It's slightly faster than choice(0, 1) since implementation is simpler (not that it will make a huge difference in most cases).

See: choice()

Example:

randBit(); // 1
randBit(); // 0

//same effect as
choice(0, 1);

randBool():Boolean

Returns a random Boolean (true or false).

Since this is very common it makes sense to abstract it into a discrete method.

Example:

randBool(); // true
randBool(); // false

randHex([size]):String

Returns a random hexadecimal string.

The default size is 6.

Example:

randHex();   // "dd8575"
randHex();   // "e6baeb"
randHex(2);  // "a2"
randHex(30); // "effd7e2ad9a4a3067e30525fab983a"

randInt([min], [max]):Number

Gets a random integer inside range or snap to min/max values.

Arguments:

  1. [min] (Number) : Minimum value. Defaults to number/MIN_INT.
  2. [max] (Number) : Maximum value. Defaults to number/MAX_INT.

Example:

randInt();      // 448740433
randInt();      // -31797596
randInt(0, 10); // 7
randInt(0, 10); // 5

randSign():Number

Returns a random "sign" (-1 or 1). Useful for multiplications.

It's slightly faster than choice(-1, 1) since implementation is simpler (not that it will make a huge difference in most cases).

See: choice()

Example:

randSign(); // -1
randSign(); // 1

//same effect as
choice(-1, 1);

random():Number

Returns a random number between 0 and 1. Same as Math.random().

random(); // 0.35435103671625257
random(); // 0.8768321881070733

Important: No methods inside mout should call Math.random() directly, they all use random/random as a proxy, that way we can inject/replace the pseudo-random number generator if needed (ie. in case we need a seeded random or a better algorithm than the native one).

Replacing the PRNG

In some cases we might need better/different algorithms than the one provided by Math.random (ie. safer, seeded).

Because of licensing issues, file size limitations and different needs we decided to not implement a custom PRNG and instead provide a easy way to override the default behavior. - issue #99

If you are using mout with a loader that supports the AMD map config, such as RequireJS, you can use it to replace the PRNG (recommended approach):

requirejs.config({
    map : {
        // all modules will load "my_custom_prng" instead of
        // "mout/random/random"
        '*' : {
            'mout/random/random' : 'my_custom_prng'
        }
    }
});

You also have the option to override random.get in case you are using mout on node.js or with a loader which doesn't support the map config:

// replace the PRNG
var n = 0;
random.get = function(){
    return ++n % 2? 0 : 1; // not so random :P
};
random(); // 0
random(); // 1
random(); // 0
random(); // 1

See this detailed explanation about PRNG in JavaScript to understand the issues with the native Math.random and also for a list of algorithms that could be used instead.

randString([length, dictionary]):String

Returns a random string.

By default returns string containing alphanumeric characters (lowercase and uppercase) with a length of 8.

Arguments:

  1. [length] (number) : Length of the string to return. Defaults to 8.
  2. [dictionary] (string) : A string containing all characters used as a dictionary for the random string construction. Defaults to alphanumeric characters (lowercase and uppercase).

Example:

randString();             // returns a string with length 8.
randString(12);           // returns a string of length 12.
randString(-1);           // returns a string of length 8.
randString(null, 'pew!'); // returns a random string of length 8 composed of 'p', 'e', 'w' and '!'.
randString(10, '0');      // always returns '0's of length 10.
randString(rand(8, 10));  // returns a random string with length between 8 and 10.

For more usage examples check specs inside /tests folder. Unit tests are the best documentation you can get...

string

String utilities.

camelCase(str):String

Convert string to "camelCase" text.

See: pascalCase(), unCamelCase()

Example

camelCase('lorem-ipsum-dolor'); // "loremIpsumDolor"
camelCase('lorem ipsum dolor'); // "loremIpsumDolor"

contains(str, substring, [fromIndex]):Boolean

Checks if string contains the given substring.

See: startsWith(), endsWith()

Example

contains('lorem', 'or');  // true
contains('lorem', 'bar'); // false

crop(str, maxChars, [append]):String

Truncate string at full words. Alias to truncate(str, maxChars, append, true);.

See: truncate()

Example

crop('lorem ipsum dolor', 10);      // "lorem..."
crop('lorem ipsum dolor', 10, '+'); // "lorem+"

endsWith(str, suffix):Boolean

Checks if string ends with specified suffix.

See: startsWith(), contains()

Example

endsWith('lorem ipsum', 'lorem'); // false
endsWith('lorem ipsum', 'ipsum'); // true

escapeHtml(str):String

Escapes the following special characters for use in HTML:

  • & becomes &amp;
  • < becomes &lt;
  • > becomes &gt;
  • ' becomes &#39;
  • " becomes &quot;

No other characters are escaped. To HTML-escape other characters as well, use a third-party library like he.

See: unescapeHtml()

Example

escapeHtml('lorem & "ipsum"'); // "lorem &amp;amp; &amp;quot;ipsum&amp;quot;"

escapeRegExp(str):String

Escape special chars to be used as literals in RegExp constructors.

Example

str = escapeRegExp('[lorem.ipsum]'); // "\\[lorem\\.ipsum\\]"
reg = new RegExp(str);               // /\[lorem\.ipsum\]/

escapeUnicode(str[, shouldEscapePrintable]):String

Unicode escape chars.

It will only escape non-printable ASCII chars unless shouldEscapePrintable is set to true.

See: unescapeUnicode()

escapeUnicode('føo bår');
// > "f\u00f8o b\u00e5r"
escapeUnicode('føo bår', true);
// > "\u0066\u00f8\u006f\u0020\u0062\u00e5\u0072"

hyphenate(str):String

Replaces spaces with hyphens, split camelCase text, remove non-word chars, remove accents and convert to lower case.

See: slugify(), underscore(), unhyphenate

hyphenate(' %# lorem ipsum  ? $  dolor'); // "lorem-ipsum-dolor"
hyphenate('spéçïãl çhârs');               // "special-chars"
hyphenate('loremIpsum');                  // "lorem-ipsum"

insert(str, index, partial):String

Inserts a partial before the given index in the provided str. If the index is larger than the length of the string the partial is appended at the end. A negative index is treated as length - index where length is the length or the string.

insert('this is a sentence', 10, 'sample '); // "this is a sample sentence"
insert('foo', 100, 'bar'); // "foobar"
insert('image.png', -4, '-large'); // "image-large.png"

interpolate(str, replacements[, syntax]):String

String interpolation. Format/replace tokens with object properties.

var tmpl = 'Hello {{name}}!';
interpolate(tmpl, {name: 'World'});       // "Hello World!"
interpolate(tmpl, {name: 'Lorem Ipsum'}); // "Hello Lorem Ipsum!"

tmpl = 'Hello {{name.first}}!';
interpolate(tmpl, {name: {first: 'Lorem'}}); // "Hello Lorem!"

It uses a mustache-like syntax by default but you can set your own format if needed. You can also use Arrays for the replacements (since Arrays are objects as well):

// matches everything inside "${}"
var syntax = /\$\{([^}]+)\}/g;
var tmpl = "Hello ${0}!";
interpolate(tmpl, ['Foo Bar'], syntax); // "Hello Foo Bar!"

lowerCase(str):String

"Safer" String.toLowerCase(). (Used internally)

Example

(null).toLowerCase();      // Error!
(undefined).toLowerCase(); // Error!
lowerCase(null);           // ""
lowerCase(undefined);      // ""

lpad(str, minLength[, char]):String

Pad string from left with char if its' length is smaller than minLen.

See: rpad()

Example

lpad('a', 5);        // "    a"
lpad('a', 5, '-');   // "----a"
lpad('abc', 3, '-'); // "abc"
lpad('abc', 4, '-'); // "-abc"

ltrim(str, [chars]):String

Remove chars or white-spaces from beginning of string.

chars is an array of chars to remove from the beginning of the string. If chars is not specified, Unicode whitespace chars will be used instead.

See: rtrim(), trim()

Example

ltrim('   lorem ipsum   ');      // "lorem ipsum   "
ltrim('--lorem ipsum--', ['-']); // "lorem ipsum--"

makePath(...args):String

Group arguments as path segments, if any of the args is null or undefined it will be ignored from resulting path. It will also remove duplicate "/".

See: array/join()

Example

makePath('lorem', 'ipsum', null, 'dolor'); // "lorem/ipsum/dolor"
makePath('foo///bar/');                    // "foo/bar/"

normalizeLineBreaks(str, [lineBreak]):String

Normalize line breaks to a single format. Defaults to Unix \n.

It handles DOS (\r\n), Mac (\r) and Unix (\n) formats.

Example

// "foo\nbar\nlorem\nipsum"
normalizeLineBreaks('foo\nbar\r\nlorem\ripsum');

// "foo\rbar\rlorem\ripsum"
normalizeLineBreaks('foo\nbar\r\nlorem\ripsum', '\r');

// "foo bar lorem ipsum"
normalizeLineBreaks('foo\nbar\r\nlorem\ripsum', ' ');

pascalCase(str):String

Convert string to "PascalCase" text.

See: camelCase()

Example

pascalCase('lorem-ipsum-dolor'); // "LoremIpsumDolor"
pascalCase('lorem ipsum dolor'); // "LoremIpsumDolor"

properCase(str):String

UPPERCASE first char of each word, lowercase other chars.

Example

properCase('loRem iPSum'); // "Lorem Ipsum"

removeNonASCII(str):String

Remove non-printable ASCII chars.

Example

removeNonASCII('äÄçÇéÉêlorem-ipsumöÖÐþúÚ'); // "lorem-ipsum"

removeNonWord(str):String

Remove non-word chars.

Example

var str = 'lorem ~!@#$%^&*()_+`-={}[]|\\:";\'/?><., ipsum';
removeNonWord(str); // "lorem - ipsum"

repeat(str, n):String

Repeat string n-times.

Example

repeat('a', 3);  // "aaa"
repeat('bc', 2); // "bcbc"
repeat('a', 0);  // ""

replace(str, search, replacements):String

Replace string(s) with the replacement(s) in the source.

search and replacements can be an array, or a single item. For every item in search, it will call str.replace with the search item and the matching replacement in replacements. If replacements only contains one replacement, it will be used for all the searches, otherwise it will use the replacement at the same index as the search.

Example

replace('foo bar', 'foo', 'test');                // "test bar"
replace('test 1 2', ['1', '2'], 'n');             // "test n n"
replace('test 1 2', ['1', '2'], ['one', 'two']);  // "test one two"
replace('123abc', [/\d/g, /[a-z]/g], ['0', '.']); // "000..."

replaceAccents(str):String

Replaces all accented chars with regular ones.

Important: Only covers Basic Latin and Latin-1 unicode chars.

Example

replaceAccents('spéçïãl çhârs'); // "special chars"

rpad(str, minLength[, char]):String

Pad string from right with char if its' length is smaller than minLen.

See: lpad()

Example

rpad('a', 5);        // "a    "
rpad('a', 5, '-');   // "a----"
rpad('abc', 3, '-'); // "abc"
rpad('abc', 4, '-'); // "abc-"

rtrim(str, [chars]):String

Remove chars or white-spaces from end of string.

chars is an array of chars to remove from the end of the string. If chars is not specified, Unicode whitespace chars will be used instead.

See: trim(), ltrim()

Example

rtrim('   lorem ipsum   ');      // "   lorem ipsum"
rtrim('--lorem ipsum--', ['-']); // "--lorem ipsum"

sentenceCase(str):String

UPPERCASE first char of each sentence and lowercase other chars.

Example

var str = 'Lorem IpSum DoLOr. maeCeNnas Ullamcor.';
sentenceCase(str); // "Lorem ipsum dolor. Maecennas ullamcor."

stripHtmlTags(str):String

Remove HTML/XML tags from string.

Example

var str = '<p><em>lorem</em> <strong>ipsum</strong></p>';
stripHtmlTags(str); // "lorem ipsum"

startsWith(str, prefix):Boolean

Checks if string starts with specified prefix.

See: endsWith(), contains()

Example

startsWith('lorem ipsum', 'lorem'); // true
startsWith('lorem ipsum', 'ipsum'); // false

slugify(str[, delimeter]):String

Convert to lower case, remove accents, remove non-word chars and replace spaces with the delimeter. The default delimeter is a hyphen.

Note that this does not split camelCase text.

See: hyphenate() and underscore()

Example

var str = 'loremIpsum dolor spéçïãl chârs';
slugify(str); // "loremipsum-dolor-special-chars"
slugify(str, '_'); // "loremipsum_dolor_special_chars"

stripMargin(str[, marginChar]):String

Strip leading characters followed by 'marginChar' from every line in a String. The default margin character is a pipe.

Example

var str = 'this\n';
str += '  |is a formatted\n';
str += '  |string';


stripMargin(str); //"this\nis a formatted\nstring"
stripMargin("this\n___#works\n___#too", '#'); //"this\nworks\ntoo"

trim(str, [chars]):String

Remove chars or white-spaces from beginning and end of string.

chars is an array of chars to remove from the beginning and end of the string. If chars is not specified, Unicode whitespace chars will be used instead.

See: rtrim(), ltrim()

Example

trim('   lorem ipsum   ');             // "lorem ipsum"
trim('-+-lorem ipsum-+-', ['-', '+']); // "lorem ipsum"

truncate(str, maxChars, [append], [onlyFullWords]):String

Limit number of chars. Returned string length will be <= maxChars.

See: crop()

Arguments

  1. str (String) : String
  2. maxChars (Number) : Maximum number of characters including append.length.
  3. [append] (String) : Value that should be added to the end of string. Defaults to "...".
  4. [onlyFullWords] (Boolean) : If it shouldn't break words. Default is false. (favor crop() since code will be clearer).

Example

truncate('lorem ipsum dolor', 11);             // "lorem ip..."
truncate('lorem ipsum dolor', 11, '+');        // "lorem ipsu+"
truncate('lorem ipsum dolor', 11, null, true); // "lorem..."

typecast(str):*

Parses string and convert it into a native value.

Example

typecast('lorem ipsum'); // "lorem ipsum"
typecast('123');         // 123
typecast('123.45');      // 123.45
typecast('false');       // false
typecast('true');        // true
typecast('null');        // null
typecast('undefined');   // undefined

unCamelCase(str, [delimiter]):String

Add the delimiter between camelCase text and convert first char of each word to lower case.

The delimiter defaults to a space character.

See: [camelCase()][#camelCase]

Example

unCamelCase('loremIpsumDolor'); // "lorem ipsum dolor"
unCamelCase('loremIpsumDolor', '-'); // "lorem-ipsum-color"

underscore(str):String

Replaces spaces with underscores, split camelCase text, remove non-word chars, remove accents and convert to lower case.

See: slugify(), hyphenate()

underscore(' %# lorem ipsum  ? $  dolor'); // "lorem_ipsum_dolor"
underscore('spéçïãl çhârs');               // "special_chars"
underscore('loremIpsum');                  // "lorem_ipsum"

unescapeHtml(str):String

Unescapes the following HTML character references back into the raw symbol they map to:

  • &amp; becomes &
  • &lt; becomes <
  • &gt; becomes >
  • &#39; becomes '
  • &quot; becomes "

No other HTML character references are unescaped. To HTML-unescape other entities as well, use a third-party library like he.

See: escapeHtml()

Example

unescapeHtml('lorem &amp;amp; &amp;quot;ipsum&amp;quot;'); // 'lorem & "ipsum"'

unescapeUnicode(str):String

Unescapes unicode char sequences.

See: escapeUnicode()

unescapeUnicode('\\u0066\\u00f8\\u006f\\u0020\\u0062\\u00e5\\u0072');
// > 'føo bår'

unhyphenate(str):String

Replaces hyphens with spaces. (only hyphens between word chars)

See : hyphenate()

Example

unhyphenate('lorem-ipsum-dolor'); // "lorem ipsum dolor"

upperCase(str):String

"Safer" String.toUpperCase(). (Used internally)

Example

(null).toUpperCase();      // Error!
(undefined).toUpperCase(); // Error!
upperCase(null);           // ""
upperCase(undefined);      // ""

WHITE_SPACES:Array

Constant array of all Unicode white-space characters.


For more usage examples check specs inside /tests folder. Unit tests are the best documentation you can get...

time

Utilities for time manipulation.

convert(value, sourceUnit, [destinationUnit]):Number

Converts time between units.

Available units: millisecond, second, minute, hour, day, week. Abbreviations: ms, s, m, h, d, w.

We do not support year and month as a time unit since their values are not fixed.

The default destinationUnit is ms.

convert(1, 'minute');    // 60000
convert(2.5, 's', 'ms'); // 2500
convert(2, 'm', 's');    // 120
convert(500, 'ms', 's'); // 0.5

now():Number

Returns the number of milliseconds elapsed since 1 January 1970 00:00:00 UTC. Uses Date.now() if available.

Example

now(); // 1335449614650

parseMs(ms):Object

Parse timestamp (milliseconds) into an object {milliseconds:number, seconds:number, minutes:number, hours:number, days:number}.

Example

// {days:27, hours:4, minutes:26, seconds:5, milliseconds:454}
parseMs(2348765454);

toTimeString(ms):String

Convert timestamp (milliseconds) into a time string in the format "[H:]MM:SS".

Example

toTimeString(12513);   // "00:12"
toTimeString(951233);  // "15:51"
toTimeString(8765235); // "2:26:05"
_Resources/node_modules/mout/

The MIT License (MIT)

Copyright (c) 2012, 2013 moutjs team and contributors (http://moutjs.com)

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

mout

http://moutjs.com/

Build Status Downloads Version

All code is library agnostic and consist mostly of helper methods that aren't directly related with the DOM, the purpose of this library isn't to replace Dojo, jQuery, YUI, Mootools, etc, but to provide modular solutions for common problems that aren't solved by most of them. Consider it as a crossbrowser JavaScript standard library.

Main goals

  • increase code reuse;
  • be clear (code should be clean/readable);
  • be easy to debug;
  • be easy to maintain;
  • follow best practices;
  • follow standards when possible;
  • don't convert JavaScript into another language!
  • be compatible with other frameworks;
  • be modular;
  • have unit tests for all modules;
  • work on multiple environments (IE7+, modern browsers, node.js);

What shouldn't be here

  • UI components;
  • CSS selector engine;
  • Event system - pub/sub;
  • Template engine;
  • Anything that isn't generic enough to be on a standard library;
  • Anything that could be a separate library and/or isn't a modular utility...

API Documentation

Online documentation can be found at http://moutjs.com/ or inside the doc folder.

FAQ / Wiki / IRC

For more info about project structure, design decisions, tips, how to contribute, build system, etc, please check the project wiki.

We also have an IRC channel #moutjs on irc.freenode.net

License

Released under the MIT License.

_Resources/node_modules/web-dev-utils/GIT-HTML-PREVIEW-TOOL/GIT-HTML-PREVIEW-TOOL-master/

GIT HTML PREVIEW TOOL .

-----------------------------------------------------

TOC
AboutHow It WorksDevelopmentContact

-----------------------------------------------------

GitJavaScriptCSS3HTML5BootstrapBitbucket

-----------------------------------------------------

Usage:

demo

GIT HTML PREVIEW TOOL was tested under the latest Google Chrome and Mozilla Firefox for GitHub & BitBucket

Still working on getting it to render html hosted on GitLabb

-----------------------------------------------------

GIT HTML PREVIEW TOOL

What it does is: load HTML using CORS proxy, then process all links, frames, scripts and styles, and load each of them using CORS proxy, so they can be evaluated by the browser.

Live Deployment

<a target="_blank" rel="noopener noreferrer"target="_blank" rel="noopener noreferrer"href="https://githtmlpreview.netlify.app/">[Live Website]

-----------------------------------------------------

➤ About

Many GitHub repositories don't use GitHub Pages to host their HTML files. GIT HTML PREVIEW TOOL allows you to render those files without cloning or downloading whole repositories. It is a client-side solution using a CORS proxy to fetch assets.

If you try to open raw version of any HTML, CSS or JS file in a web browser directly from GitHub, all you will see is a source code. GitHub forces them to use the "text/plain" content-type, so they cannot be interpreted. This script overrides it by using a CORS proxy.


Cross-Origin Resource Sharing (CORS) is a security mechanism that uses additional HTTP headers to tell browsers to give a web application running at one origin, access to selected resources from a different origin. A web application executes a cross-origin HTTP request when it requests a resource(Images, Scripts, CSS files, etc.)that has a different origin (domain, protocol, or port) from its own.

Cross-origin requests, however, mean that servers must implement ways to handle requests from origins outside of their own. CORS allows servers to specify who (i.e., which origins) can access the assets on the server, among many other things.

Access-Control-Allow-Origin Header When Site A tries to fetch content from Site B, Site B can send an Access-Control-Allow-Origin response header to tell the browser that the content of this page is accessible to certain origins. (An origin is a domain, plus a scheme and port number.) By default, Site B's pages are not accessible to any other origin; using the Access-Control-Allow-Origin header opens a door for cross-origin access by specific requesting origins. The Access-Control-Allow-Origin header is critical to resource security. You can find a description of each CORS header at the following: CORS Headers. Pre-Flight Request Most servers will allow GET requests but may block requests to modify resources on the server. Servers don't just blindly block such requests though; they have a process in place that first checks and then communicates to the client (your web browser) which requests are allowed. When a request is made using any of the following HTTP request methods, a standard preflight request will be made before the original request. PUT DELETE CONNECT OPTIONS TRACE PATCH Preflight requests use the OPTIONS header. The preflight request is sent before the original request, hence the term "preflight." The purpose of the preflight request is to determine whether or not the original request is safe (for example, a DELETE request). The server will respond to the preflight request and indicate whether or not the original request is safe. If the server specifies that the original request is safe, it will allow the original request. Otherwise, it will block the original request.


➤ Bryan Guner


(Full-stack software developer)


Portfolio<a target="_blank" rel="noopener noreferrer"target="_blank" rel="noopener noreferrer"href="https://github.com/bgoonz/resume-cv-portfolio-samples/blob/master/2021-resume/bryan-guner-resume-2021.pdf" download>Resume PDFBryan's emailBlogLinkedinAngelListGitHub bgoonz


-----------------------------------------------------

logo


-----------------------------------------------------

➤ Development:

(() => {
  
  const previewForm = document.getElementById('previewform');

  const url = location.search.substring(1).replace(/\/\/github\.com/, '//raw.githubusercontent.com').replace(/\/blob\//, '/'); //Get URL of the raw file

  const replaceAssets = () => {
        let frame;
        let a;
        let link;
        const links = [];
        let script;
        const scripts = [];
        let i;
        let href;
        let src;
        //Framesets
        if (document.querySelectorAll('frameset').length)
      return; //Don't replace CSS/JS if it's a frameset, because it will be erased by document.write()
        //Frames
        frame = document.querySelectorAll('iframe[src],frame[src]');
        for (i = 0; i < frame.length; ++i) {
      src = frame[i].src; //Get absolute URL
      if (src.indexOf('//raw.githubusercontent.com') > 0 || src.indexOf('//bitbucket.org') > 0) { //Check if it's from raw.github.com or bitbucket.org
        frame[i].src = '//' + location.hostname + location.pathname + '?' + src; //Then rewrite URL so it can be loaded using CORS proxy
      }
    }
        //Links
        a = document.querySelectorAll('a[href]');
        for (i = 0; i < a.length; ++i) {
      href = a[i].href; //Get absolute URL
      if (href.indexOf('#') > 0) { //Check if it's an anchor
        a[i].href = '//' + location.hostname + location.pathname + location.search + '#' + a[i].hash.substring(1); //Then rewrite URL with support for empty anchor
      } else if ((href.indexOf('//raw.githubusercontent.com') > 0 || href.indexOf('//bitbucket.org') > 0) && (href.indexOf('.html') > 0 || href.indexOf('.htm') > 0)) { //Check if it's from raw.github.com or bitbucket.org and to HTML files
        a[i].href = '//' + location.hostname + location.pathname + '?' + href; //Then rewrite URL so it can be loaded using CORS proxy
      }
    }
        //Stylesheets
        link = document.querySelectorAll('link[rel=stylesheet]');
        for (i = 0; i < link.length; ++i) {
      href = link[i].href; //Get absolute URL
      if (href.indexOf('//raw.githubusercontent.com') > 0 || href.indexOf('//bitbucket.org') > 0) { //Check if it's from raw.github.com or bitbucket.org
        links.push(fetchProxy(href, null, 0)); //Then add it to links queue and fetch using CORS proxy
      }
    }
        Promise.all(links).then(res => {
      for (i = 0; i < res.length; ++i) {
        loadCSS(res[i]);
      }
    });
        //Scripts
        script = document.querySelectorAll('script[type="text/htmlpreview"]');
        for (i = 0; i < script.length; ++i) {
      src = script[i].src; //Get absolute URL
      if (src.indexOf('//raw.githubusercontent.com') > 0 || src.indexOf('//bitbucket.org') > 0) { //Check if it's from raw.github.com or bitbucket.org
        scripts.push(fetchProxy(src, null, 0)); //Then add it to scripts queue and fetch using CORS proxy
      } else {
        script[i].removeAttribute('type');
        scripts.push(script[i].innerHTML); //Add inline script to queue to eval in order
      }
    }
        Promise.all(scripts).then(res => {
      for (i = 0; i < res.length; ++i) {
        loadJS(res[i]);
      }
      document.dispatchEvent(new Event('DOMContentLoaded', {bubbles: true, cancelable: true})); //Dispatch DOMContentLoaded event after loading all scripts
    });
    };

  const loadHTML = data => {
    if (data) {
      data = data.replace(/<head([^>]*)>/i, '<head$1><base href="' + url + '">').replace(/<script(\s*src=["'][^"']*["'])?(\s*type=["'](text|application)\/javascript["'])?/gi, '<script type="text/htmlpreview"$1'); //Add <base> just after <head> and replace <script type="text/javascript"> with <script type="text/htmlpreview">
      setTimeout(() => {
        document.open();
        document.write(data);
        document.close();
        replaceAssets();
      }, 10); //Delay updating document to have it cleared before
    }
  };

  var loadCSS = data => {
    if (data) {
      const style = document.createElement('style');
      style.innerHTML = data;
      document.head.appendChild(style);
    }
  };

  var loadJS = data => {
    if (data) {
      const script = document.createElement('script');
      script.innerHTML = data;
      document.body.appendChild(script);
    }
  };
  
  var fetchProxy = (url, options, i) => {
    const proxy = [
      'https://cors-anywhere.herokuapp.com/',
      'https://yacdn.org/proxy/',
      'https://api.codetabs.com/v1/proxy/?quest='
    ];
    return fetch(proxy[i] + url, options).then(res => {
      if (!res.ok) throw new Error('Cannot load ' + url + ': ' + res.status + ' ' + res.statusText);
      return res.text();
    }).catch(error => {
      if (i === proxy.length - 1)
        throw error;
      return fetchProxy(url, options, i + 1);
    });
  };

  if (url && url.indexOf(location.hostname) < 0)
    fetch(url).then(res => {
      if (!res.ok) throw new Error('Cannot load ' + url + ': ' + res.status + ' ' + res.statusText);
      return res.text();
    }).then(loadHTML).catch(error => {
      console.error(error);
      previewForm.style.display = 'block';
      previewForm.innerText = error;
    });
  else
    previewForm.style.display = 'block';

})();
_Resources/node_modules/web-dev-utils/Markdown-Templates/Markdown-Templates-master/

gr# Product Name

Short blurb about what your product does.

NPM Version Build Status Downloads Stats

One to two paragraph statement about your product and what it does.

Installation

OS X & Linux:

npm install my-crazy-module --save

Windows:

edit autoexec.bat

Usage example

A few motivating and useful examples of how your product can be used. Spice this up with code blocks and potentially more screenshots.

For more examples and usage, please refer to the Wiki.

Development setup

Describe how to install all development dependencies and how to run an automated test-suite of some kind. Potentially do this for multiple platforms.

make install
npm test

Release History

  • 0.2.1
    • CHANGE: Update docs (module code remains unchanged)
  • 0.2.0
    • CHANGE: Remove setDefaultXYZ()
    • ADD: Add init()
  • 0.1.1
    • FIX: Crash when calling baz() (Thanks @GenerousContributorName!)
  • 0.1.0
    • The first proper release
    • CHANGE: Rename foo() to bar()
  • 0.0.1
    • Work in progress

Meta

Your Name – @YourTwitterYourEmail@example.com

Distributed under the XYZ license. See LICENSE for more information.

https://github.com/yourname/github-link

Contributing

  1. Fork it (https://github.com/yourname/yourproject/fork)
  2. Create your feature branch (git checkout -b feature/fooBar)
  3. Commit your changes (git commit -am 'Add some fooBar')
  4. Push to the branch (git push origin feature/fooBar)
  5. Create a new Pull Request

Contributors Forks Stargazers Issues MIT License LinkedIn


Logo

project_title

project_description
Explore the docs »

View Demo · Report Bug · Request Feature

Table of Contents

  1. About The Project
  2. Getting Started
  3. Usage
  4. Roadmap
  5. Contributing
  6. License
  7. Contact
  8. Acknowledgements

About The Project

Product Name Screen Shot

Here's a blank template to get started: To avoid retyping too much info. Do a search and replace with your text editor for the following: github_username, repo_name, twitter_handle, email, project_title, project_description

Built With

Getting Started

To get a local copy up and running follow these simple steps.

Prerequisites

This is an example of how to list things you need to use the software and how to install them.

  • npm
    npm install npm@latest -g

Installation

  1. Clone the repo
    git clone https://github.com/github_username/repo_name.git
  2. Install NPM packages
    npm install

Usage

Use this space to show useful examples of how a project can be used. Additional screenshots, code examples and demos work well in this space. You may also link to more resources.

For more examples, please refer to the Documentation

Roadmap

See the open issues for a list of proposed features (and known issues).

Contributing

Contributions are what make the open source community such an amazing place to be learn, inspire, and create. Any contributions you make are greatly appreciated.

  1. Fork the Project
  2. Create your Feature Branch (git checkout -b feature/AmazingFeature)
  3. Commit your Changes (git commit -m 'Add some AmazingFeature')
  4. Push to the Branch (git push origin feature/AmazingFeature)
  5. Open a Pull Request

License

Distributed under the MIT License. See LICENSE for more information.

Contact

Your Name - @twitter_handle - email

Project Link: https://github.com/github_username/repo_name

Acknowledgements

Project name

GitHub repo size GitHub contributors GitHub stars GitHub forks Twitter Follow

Project name is a <utility/tool/feature> that allows <insert_target_audience> to do <action/task_it_does>.

Additional line of information text about what the project does. Your introduction should be around 2 or 3 sentences. Don't go overboard, people won't read it.

Prerequisites

Before you begin, ensure you have met the following requirements:

  • You have installed the latest version of <coding_language/dependency/requirement_1>
  • You have a <Windows/Linux/Mac> machine. State which OS is supported/which is not.
  • You have read <guide/link/documentation_related_to_project>.

Installing <project_name>

To install <project_name>, follow these steps:

Linux and macOS:

<install_command>

Windows:

<install_command>

Using <project_name>

To use <project_name>, follow these steps:

<usage_example>

Add run commands and examples you think users will find useful. Provide an options reference for bonus points!

Contributing to <project_name>

To contribute to <project_name>, follow these steps:

  1. Fork this repository.
  2. Create a branch: git checkout -b <branch_name>.
  3. Make your changes and commit them: git commit -m '<commit_message>'
  4. Push to the original branch: git push origin <project_name>/<location>
  5. Create the pull request.

Alternatively see the GitHub documentation on creating a pull request.

Contributors

Thanks to the following people who have contributed to this project:

You might want to consider using something like the All Contributors specification and its emoji key.

Contact

If you want to contact me you can reach me at your_email@address.com.

License

This project uses the following license: <license_name>.

Title


  • Description:

/* Description here */


ToC:


Main Notes:









Resource Links:


10 X 10 Table

                   
                   
                   
                   
                   
                   
                   
                   
                   
                   

<a target="_blank" rel="noopener noreferrer"target="_blank" rel="noopener noreferrer"name="headers"/>

Headers

# H1
## H2
### H3
#### H4
##### H5
###### H6

Alternatively, for H1 and H2, an underline-ish style:

Alt-H1
======

Alt-H2
------

H1

H2

H3

H4

H5
H6

Alternatively, for H1 and H2, an underline-ish style:

Alt-H1

Alt-H2

<a target="_blank" rel="noopener noreferrer"target="_blank" rel="noopener noreferrer"name="emphasis"/>

Emphasis

Emphasis, aka italics, with *asterisks* or _underscores_.

Strong emphasis, aka bold, with **asterisks** or __underscores__.

Combined emphasis with **asterisks and _underscores_**.

Strikethrough uses two tildes. ~~Scratch this.~~

Emphasis, aka italics, with asterisks or underscores.

Strong emphasis, aka bold, with asterisks or underscores.

Combined emphasis with asterisks and underscores.

Strikethrough uses two tildes. Scratch this.

<a target="_blank" rel="noopener noreferrer"target="_blank" rel="noopener noreferrer"name="lists"/>

Lists

(In this example, leading and trailing spaces are shown with with dots: ⋅)

1. First ordered list item
2. Another item
⋅⋅* Unordered sub-list. 
1. Actual numbers don't matter, just that it's a number
⋅⋅1. Ordered sub-list
4. And another item.

⋅⋅⋅You can have properly indented paragraphs within list items. Notice the blank line above, and the leading spaces (at least one, but we'll use three here to also align the raw Markdown).

⋅⋅⋅To have a line break without a paragraph, you will need to use two trailing spaces.⋅⋅
⋅⋅⋅Note that this line is separate, but within the same paragraph.⋅⋅
⋅⋅⋅(This is contrary to the typical GFM line break behaviour, where trailing spaces are not required.)

* Unordered list can use asterisks
- Or minuses
+ Or pluses
  1. First ordered list item
  2. Another item
  • Unordered sub-list.
  1. Actual numbers don't matter, just that it's a number

  2. Ordered sub-list

  3. And another item.

    You can have properly indented paragraphs within list items. Notice the blank line above, and the leading spaces (at least one, but we'll use three here to also align the raw Markdown).

    To have a line break without a paragraph, you will need to use two trailing spaces.
    Note that this line is separate, but within the same paragraph.
    (This is contrary to the typical GFM line break behaviour, where trailing spaces are not required.)

  • Unordered list can use asterisks
  • Or minuses
  • Or pluses

<a target="_blank" rel="noopener noreferrer"target="_blank" rel="noopener noreferrer"name="links"/>

Links

There are two ways to create links.

[I'm an inline-style link](https://www.google.com)

[I'm an inline-style link with title](https://www.google.com "Google's Homepage")

[I'm a reference-style link][Arbitrary case-insensitive reference text]

[I'm a relative reference to a repository file](../blob/master/LICENSE)

[You can use numbers for reference-style link definitions][1]

Or leave it empty and use the [link text itself].

URLs and URLs in angle brackets will automatically get turned into links. 
http://www.example.com or <http://www.example.com> and sometimes 
example.com (but not on Github, for example).

Some text to show that the reference links can follow later.

[arbitrary case-insensitive reference text]: https://www.mozilla.org
[1]: http://slashdot.org
[link text itself]: http://www.reddit.com

I'm an inline-style link

I'm an inline-style link with title

I'm a reference-style link

I'm a relative reference to a repository file

You can use numbers for reference-style link definitions

Or leave it empty and use the link text itself.

URLs and URLs in angle brackets will automatically get turned into links. http://www.example.com or http://www.example.com and sometimes example.com (but not on Github, for example).

Some text to show that the reference links can follow later.

<a target="_blank" rel="noopener noreferrer"target="_blank" rel="noopener noreferrer"name="images"/>

Images

Here's our logo (hover to see the title text):

Inline-style: 
![alt text](https://github.com/adam-p/markdown-here/raw/master/src/common/images/icon48.png "Logo Title Text 1")

Reference-style: 
![alt text][logo]

[logo]: https://github.com/adam-p/markdown-here/raw/master/src/common/images/icon48.png "Logo Title Text 2"

Here's our logo (hover to see the title text):

Inline-style: alt text

Reference-style: alt text

<a target="_blank" rel="noopener noreferrer"target="_blank" rel="noopener noreferrer"name="code"/>

Code and Syntax Highlighting

Code blocks are part of the Markdown spec, but syntax highlighting isn't. However, many renderers -- like Github's and Markdown Here -- support syntax highlighting. Which languages are supported and how those language names should be written will vary from renderer to renderer. Markdown Here supports highlighting for dozens of languages (and not-really-languages, like diffs and HTTP headers); to see the complete list, and how to write the language names, see the highlight.js demo page.

Inline `code` has `back-ticks around` it.

Inline code has back-ticks around it.

Blocks of code are either fenced by lines with three back-ticks ```, or are indented with four spaces. I recommend only using the fenced code blocks -- they're easier and only they support syntax highlighting.

```javascript
var s = "JavaScript syntax highlighting";
alert(s);
```
 
```python
s = "Python syntax highlighting"
print s
```
 
```
No language indicated, so no syntax highlighting. 
But let's throw in a <b>tag</b>.
```
var s = "JavaScript syntax highlighting";
alert(s);
s = "Python syntax highlighting"
print s
No language indicated, so no syntax highlighting in Markdown Here (varies on Github). 
But let's throw in a <b>tag</b>.

<a target="_blank" rel="noopener noreferrer"target="_blank" rel="noopener noreferrer"name="tables"/>

Tables

Tables aren't part of the core Markdown spec, but they are part of GFM and Markdown Here supports them. They are an easy way of adding tables to your email -- a task that would otherwise require copy-pasting from another application.

Colons can be used to align columns.

| Tables        | Are           | Cool  |
| ------------- |:-------------:| -----:|
| col 3 is      | right-aligned | $1600 |
| col 2 is      | centered      |   $12 |
| zebra stripes | are neat      |    $1 |

There must be at least 3 dashes separating each header cell.
The outer pipes (|) are optional, and you don't need to make the 
raw Markdown line up prettily. You can also use inline Markdown.

Markdown | Less | Pretty
--- | --- | ---
*Still* | `renders` | **nicely**
1 | 2 | 3

Colons can be used to align columns.

Tables Are Cool
col 3 is right-aligned $1600
col 2 is centered $12
zebra stripes are neat $1

There must be at least 3 dashes separating each header cell. The outer pipes (|) are optional, and you don't need to make the raw Markdown line up prettily. You can also use inline Markdown.

Markdown Less Pretty
Still renders nicely
1 2 3

<a target="_blank" rel="noopener noreferrer"target="_blank" rel="noopener noreferrer"name="blockquotes"/>

Blockquotes

> Blockquotes are very handy in email to emulate reply text.
> This line is part of the same quote.

Quote break.

> This is a very long line that will still be quoted properly when it wraps. Oh boy let's keep writing to make sure this is long enough to actually wrap for everyone. Oh, you can *put* **Markdown** into a blockquote. 

Blockquotes are very handy in email to emulate reply text. This line is part of the same quote.

Quote break.

This is a very long line that will still be quoted properly when it wraps. Oh boy let's keep writing to make sure this is long enough to actually wrap for everyone. Oh, you can put Markdown into a blockquote.

<a target="_blank" rel="noopener noreferrer"target="_blank" rel="noopener noreferrer"name="html"/>

Inline HTML

You can also use raw HTML in your Markdown, and it'll mostly work pretty well.

<dl>
  <dt>Definition list</dt>
  <dd>Is something people use sometimes.</dd>

  <dt>Markdown in HTML</dt>
  <dd>Does *not* work **very** well. Use HTML <em>tags</em>.</dd>
</dl>
Definition list
Is something people use sometimes.
Markdown in HTML
Does *not* work **very** well. Use HTML tags.

<a target="_blank" rel="noopener noreferrer"target="_blank" rel="noopener noreferrer"name="hr"/>

Horizontal Rule

Three or more...

---

Hyphens

***

Asterisks

___

Underscores

Three or more...


Hyphens


Asterisks


Underscores

<a target="_blank" rel="noopener noreferrer"target="_blank" rel="noopener noreferrer"name="lines"/>

Line Breaks

My basic recommendation for learning how line breaks work is to experiment and discover -- hit <Enter> once (i.e., insert one newline), then hit it twice (i.e., insert two newlines), see what happens. You'll soon learn to get what you want. "Markdown Toggle" is your friend.

Here are some things to try out:

Here's a line for us to start with.

This line is separated from the one above by two newlines, so it will be a *separate paragraph*.

This line is also a separate paragraph, but...
This line is only separated by a single newline, so it's a separate line in the *same paragraph*.

Here's a line for us to start with.

This line is separated from the one above by two newlines, so it will be a separate paragraph.

This line is also begins a separate paragraph, but...
This line is only separated by a single newline, so it's a separate line in the same paragraph.

(Technical note: Markdown Here uses GFM line breaks, so there's no need to use MD's two-space line breaks.)

<a target="_blank" rel="noopener noreferrer"target="_blank" rel="noopener noreferrer"name="videos"/>

YouTube Videos

They can't be added directly but you can add an image with a link to the video like this:

<a target="_blank" rel="noopener noreferrer"target="_blank" rel="noopener noreferrer"href="http://www.youtube.com/watch?feature=player_embedded&v=YOUTUBE_VIDEO_ID_HERE
" target="_blank"><img src="http://img.youtube.com/vi/YOUTUBE_VIDEO_ID_HERE/0.jpg" 
alt="IMAGE ALT TEXT HERE" width="240" height="180" border="10" /></a>

Or, in pure Markdown, but losing the image sizing and border:

[![IMAGE ALT TEXT HERE](http://img.youtube.com/vi/YOUTUBE_VIDEO_ID_HERE/0.jpg)](http://www.youtube.com/watch?v=YOUTUBE_VIDEO_ID_HERE)

Project Title

One Paragraph of project description goes here

Getting Started

These instructions will get you a copy of the project up and running on your local machine for development and testing purposes. See deployment for notes on how to deploy the project on a live system.

Prerequisites

What things you need to install the software and how to install them

Give examples

Installing

A step by step series of examples that tell you how to get a development env running

Say what the step will be

Give the example

And repeat

until finished

End with an example of getting some data out of the system or using it for a little demo

Running the tests

Explain how to run the automated tests for this system

Break down into end to end tests

Explain what these tests test and why

Give an example

And coding style tests

Explain what these tests test and why

Give an example

Deployment

Add additional notes about how to deploy this on a live system

Built With

  • Dropwizard - The web framework used
  • Maven - Dependency Management
  • ROME - Used to generate RSS Feeds

Contributing

Please read CONTRIBUTING.md for details on our code of conduct, and the process for submitting pull requests to us.

Versioning

We use SemVer for versioning. For the versions available, see the tags on this repository.

Authors

  • Bryan Guner - Initial work - bgoonz

See also the list of contributors who participated in this project.

License

This project is licensed under the MIT License - see the LICENSE.md file for details

Acknowledgments

  • Hat tip to anyone whose code was used
  • Inspiration
  • etc

logo

Title

Subtitle

TOC
AboutFeaturesHow It WorksInstallationDevelopmentContact

-----------------------------------------------------

A 1-5 sentence summary of what the app is.
1-3 sentences ideal.
Markdown tip: Add two spaces at the end of a line to create a line break.

Splashy 100%-width image

##Try the Demo! <a target="_blank" rel="noopener noreferrer"target="_blank" rel="noopener noreferrer"href="">[Live Website]


-----------------------------------------------------

About

● See Website ●
(Inspired by app name)

Animated gif example of app in action, or interesting detail, etc.

Describe overview of app, themes and philosophy, inspiration, audience, or whatever... 1-2 paragraphs


Image 1 Image 2
Image 1 Image 2

-----------------------------------------------------

Features

  • Key action word a feature here.
  • Emphasize action for this feature.
  • Feature 3 highlights this benefit.

##For the Future

An optional brief note describing scheduling or other planning details.

  • Major (high priority) A major feature
  • Major A major feature
  • Minor (low priority) A minor feature
  • Maybe Undecided ideas or brainstorming

-----------------------------------------------------

##1. Step One

Screenshot, animated gif, diagram, etc illustrating this step

  • To do a thing, follow this step.
  • TIP This is a helpful tip.
  • NOTE This is note about something.
  • WARNING! This is a warning!

Optional Special Section!
For any additional asides. Maybe illustrating a specific example, a table of information, a code snippet, or 'fun facts' or quotes!

  1. A list
  2. could be
  3. nice too
Header A Header B
A B
Optional extra image(s)

##How to Use Feature ABC Repeat the pattern.

##Troubleshooting Z Repeat the pattern.

Installation

  1. Create a new postgres database and owner.
  2. Create a .env file matching the .env.example file and your new postgres information.
  3. Migrate the database with npx sequelize-cli db:migrate.
  4. Seed the migration with npx sequelize-cli db:seed:all.
  5. Run locally with npm start.

##Get started on Heroku - Account, Database, Config Vars

  1. Install the Heroku CLI, if you haven't done so already.
  2. Create a free Heroku account.
  3. Login and create a new Heroku app.
  4. Navigate to the Resources tab an set up a 'Heroku Postgres' database for the app.
  5. Select the 'Hobby Dev - Free' plan.
  6. Navigate to the Settings tab. Click 'Reveal Config Vars'. Set the environment variables needed to run the app.
  • NOTE NEVER check in .env files or any private keys. Environment variables set in an .env file won't work in Heroku anyway.
  • NOTE See the DATABASE_URL is already set. This is done when the Heroku Postgres database was set up. Therefore, DB_USERNAME, DB_PASSWORD, and DB_DATABASE arent' required.

##Configure the app to use the Heroku Postgres database There are two ways to configure the production environment:

  1. With dotenv and a .sequelizerc file that points to a config/database.js file.
  2. The Sequelize CLI's auto-generated config.json file.

With .sequelizerc and dotenv Update the config/database.js file with a production key like so.

// config/database.js
// ...
module.exports = {
  development: {
    // ...
  },
  production: {
    use_env_variable: 'DATABASE_URL',
    dialect: 'postgres',
    dialectOptions: {ssl: true},
    seederStorage: 'sequelize',
  }
}

With Sequelize CLI's config.json Change the production entry to look like this:

"production": {
  "dialect": "postgres",
  "seederStorage": "sequelize",
  "use_env_variable": "DATABASE_URL"
}

➤ Push to Heroku

  1. In the root of the app's repo directory, log into Heroku with heroku login.
  2. Add a new remote to GitHub configuration with heroku git:remote -a <<app-name-here>>.
  3. Add all changes with git add ..
  4. Commit changes with git commit -m "<<Add message here>>". (Optionally, git commit -am Adds and commits in one command.)
  5. Push changes to Heroku with git push Heroku.
  6. You should see a successful build image.

-----------------------------------------------------

remote: -----> Launching...
remote:        Released v5
remote:        https://«your-app-name».herokuapp.com/ deployed to Heroku
remote:
remote: Verifying deploy... done.
To https://git.heroku.com/«app-name-here».git

➤ Run migrations on Heroku

  1. To migrate your Heroku Postgres database, run the migration command prefaced with heroku run inside the repo.
heroku run npx sequelize-cli db:migrate
  1. To seed, preface the seed command with heroku run as well.
heroku run npx sequelize-cli db:seed:all
  1. To roll back, instead of dropping the database, first try to migrate down and up (shown below). If this doesn't work, reset the entire database by removing and adding the 'Heroku Postgres' add-on again, then migrating and seeding as the first time.
heroku run npx sequelize-cli db:seed:undo:all
heroku run npx sequelize-cli db:migrate:undo:all
heroku run npx sequelize-cli db:migrate
heroku run npx sequelize-cli db:seed:all

-----------------------------------------------------

➤ Development

DEV TOC
TechnologiesConceptModelsRoutesWireframesCode HighlightsDev Snapshots

[ See full dev notes HERE ]
The full notes on this project's development are kept in a separate document linked above.
It details the technical aspects of this project's development.
A few sample snapshots are below from the development process.

Snapshot 1 Snapshot 2 Snapshot 3


-----------------------------------------------------

➤Contact

Thank you very much for your interest in this project.
Feel free to reach out to provide feedback, bug reports, or anything else :) .

Bryan Gimer

##Bryan Guner (Full-stack software developer)

Portfolio <a target="_blank" rel="noopener noreferrer"target="_blank" rel="noopener noreferrer"href="https://github.com/bgoonz/resume-cv-portfolio-samples/blob/master/2021-resume/bryan-guner-resume-2021.pdf" download>Resume PDF Bryan's email Blog Linkedin AngelList GitHub bgoonz



Contributors Forks Stargazers Issues MIT License LinkedIn


Logo

Best-README-Template

An awesome README template to jumpstart your projects!
Explore the docs »

View Demo · Report Bug · Request Feature

Table of Contents
  1. About The Project
  2. Getting Started
  3. Usage
  4. Roadmap
  5. Contributing
  6. License
  7. Contact
  8. Acknowledgements

About The Project

Product Name Screen Shot

There are many great README templates available on GitHub, however, I didn't find one that really suit my needs so I created this enhanced one. I want to create a README template so amazing that it'll be the last one you ever need -- I think this is it.

Here's why:

  • Your time should be focused on creating something amazing. A project that solves a problem and helps others
  • You shouldn't be doing the same tasks over and over like creating a README from scratch
  • You should element DRY principles to the rest of your life 😄

Of course, no one template will serve all projects since your needs may be different. So I'll be adding more in the near future. You may also suggest changes by forking this repo and creating a pull request or opening an issue. Thanks to all the people have have contributed to expanding this template!

A list of commonly used resources that I find helpful are listed in the acknowledgements.

Built With

This section should list any major frameworks that you built your project using. Leave any add-ons/plugins for the acknowledgements section. Here are a few examples.

Getting Started

This is an example of how you may give instructions on setting up your project locally. To get a local copy up and running follow these simple example steps.

Prerequisites

This is an example of how to list things you need to use the software and how to install them.

  • npm
    npm install npm@latest -g

Installation

  1. Get a free API Key at https://example.com
  2. Clone the repo
    git clone https://github.com/your_username_/Project-Name.git
  3. Install NPM packages
    npm install
  4. Enter your API in config.js
    const API_KEY = 'ENTER YOUR API';

Usage

Use this space to show useful examples of how a project can be used. Additional screenshots, code examples and demos work well in this space. You may also link to more resources.

For more examples, please refer to the Documentation

Roadmap

See the open issues for a list of proposed features (and known issues).

Contributing

Contributions are what make the open source community such an amazing place to be learn, inspire, and create. Any contributions you make are greatly appreciated.

  1. Fork the Project
  2. Create your Feature Branch (git checkout -b feature/AmazingFeature)
  3. Commit your Changes (git commit -m 'Add some AmazingFeature')
  4. Push to the Branch (git push origin feature/AmazingFeature)
  5. Open a Pull Request

License

Distributed under the MIT License. See LICENSE for more information.

Contact

Your Name - @your_twitter - email@example.com

Project Link: https://github.com/your_username/repo_name

Acknowledgements

_Resources/node_modules/web-dev-utils/personal-utilities/copy-2-clip/

How to Copy to Clipboard text from and
 tags using Jquery and JS?

$(document).ready(function() {
  $('code, pre').append('<span class="command-copy" ><i class="fa fa-clipboard" aria-hidden="true"></i></span>');

  $('code span.command-copy').click(function(e) {
    var text = $(this).parent().text().trim(); //.text();
    var copyHex = document.createElement('input');
    copyHex.value = text
    document.body.appendChild(copyHex);
    copyHex.select();
    document.execCommand('copy');
    console.log(copyHex.value)
    document.body.removeChild(copyHex);
  });


  $('pre span.command-copy').click(function(e) {
    var text = $(this).parent().text().trim();
    var copyHex = document.createElement('input');
    copyHex.value = text
    document.body.appendChild(copyHex);
    copyHex.select();
    document.execCommand('copy');
    console.log(copyHex.value)
    document.body.removeChild(copyHex);
  });
})

code,
pre {
  position: relative;
}

code,
pre {
  display: block;
  padding: 20px;
  background: #f2f2f2;
  color: #555755;
}

span.command-copy {
  position: absolute;
  top: 10px;
  right: 10px;
  opacity: .6;
  font-size: 20px;
  color: #555755;
}

span.command-copy:hover {
  cursor: pointer;
}
<!DOCTYPE html>
<html lang="en">

<head>
      <meta charset="utf-8">
      <meta http-equiv="X-UA-Compatible" content="IE=edge">
      <meta name="viewport" content="width=device-width, initial-scale=1">
      <meta name="Author" content="Bryan Guner">
      <meta http-equiv="X-UA-Compatible" content="IE=edge">
      <!-- Mobile Meta -->
      <meta name="viewport" content="width=device-width, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no">
      <!-- Site Meta -->
      <meta name="description" content="Resource-sharing-hub">
      <meta name="author" content="Bryan Guner">
      <!-- Site Icons -->
      <!-- Basic -->
      <meta charset="utf-8">
      <meta http-equiv="X-UA-Compatible" content="IE=edge">
      <!-- Mobile Meta -->
      <meta name="viewport" content="width=device-width, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no"><meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>

    
    <!--------------------------------------------------------------------------->
    
    
    
    <!------------------------NEED JQUERY TO ENABLE SCRIPT BELOW----------------->
    
    
    
#    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css"
        integrity="sha384-wvfXpqpZZVQGK6TAh5PVlGOfQNHSoD2xbE+QkPxCAFlNEevoEH3Sl0sibVcOQVnN" crossorigin="anonymous">

#    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
    
    
        
    <!--------------------------------------------------------------------------->

    
</head>

<body class="lang-js">
_Resources/node_modules/web-dev-utils/

-testing

logo

MY WEB-DEV UTILITIES NPM PACKAGE

This code is not exclusivley written by me ... it is just a list of files I use often during website development... use at your own risk

Copy-2-Clipboard:


Git-Html Preview-Tool:


Markdown Templates:


Text Tools:


Automatic Table Of Contents Generator:


Text-File-2-JS-Array:


Usage:

npm i web-dev-utils
---
.
├── GIT-HTML-PREVIEW-TOOL
│   └── GIT-HTML-PREVIEW-TOOL-master
├── Markdown-Templates-master
│   └── Markdown-Templates-master
│       └── images
├── TexTools-master
│   └── TexTools-master
│       ├── backup-stable-build
│       │   ├── css
│       │   └── js
│       ├── css
│       ├── js
│       └── sandbox
├── bootstrap-4.3.1-dist
│   ├── css
│   └── js
├── jquery
│   ├── dist
│   ├── external
│   │   └── sizzle
│   │       └── dist
│   └── src
│       ├── ajax
│       │   └── var
│       ├── attributes
│       ├── core
│       │   └── var
│       ├── css
│       │   └── var
│       ├── data
│       │   └── var
│       ├── deferred
│       ├── deprecated
│       ├── effects
│       ├── event
│       ├── exports
│       ├── manipulation
│       │   └── var
│       ├── queue
│       ├── traversing
│       │   └── var
│       └── var
├── loadashes6
│   └── lodash
│       └── fp
├── mout
│   ├── array
│   ├── collection
│   ├── date
│   │   └── i18n
│   ├── doc
│   ├── function
│   ├── lang
│   ├── math
│   ├── number
│   ├── object
│   ├── queryString
│   ├── random
│   ├── src
│   │   ├── array
│   │   ├── collection
│   │   ├── date
│   │   │   └── i18n
│   │   ├── function
│   │   ├── lang
│   │   ├── math
│   │   ├── number
│   │   ├── object
│   │   ├── queryString
│   │   ├── random
│   │   ├── string
│   │   └── time
│   ├── string
│   └── time
└── personal-utilities
    ├── Auto-table-Of-Contents
    ├── copy-2-clip
    ├── css
    ├── html
    ├── js
    └── prism

81 directories
_Resources/node_modules/web-dev-utils/TexTools/TexTools-master/

Deployment:

deployment

TexTools .

-----------------------------------------------------

TOC
AboutFeaturesHow It WorksInstallationDevelopmentContact

logo

-----------------------------------------------------

GitjQueryJavaScriptNodeJSCSS3HTML5BootstrapBitbucketAdobe XDRepl.it

-----------------------------------------------------

Usage:

-----------------------------------------------------

Tools

*8 text manipulation tools: .

  1. Duplicate Remover (duplicate lines... Case and whitespace sensative)

-----------------------------------------------------

  1. Find and Replace

-----------------------------------------------------

  1. Compare Text Files: compares text files and if common text is detected between them only one of them will retain the text that previously existed in both.

-----------------------------------------------------

  1. Add Prefix/Suffix (by line.. not by file)

-----------------------------------------------------

  1. White Space remover (It removes all the whitespace within your text. I use it for creating javascript for iMacros for Firefox)

-----------------------------------------------------

  1. Sort Text Lines (It sorts text lines alphabetically in ascending and descending order)

-----------------------------------------------------

  1. Replace Lines Breaks (Replace line breaks with some text. One of the example where it can be used is to convert a normal text file with line breaks to csv type file.)

-----------------------------------------------------

  1. Letter Case Converter (Converts the letter case of your text. Currently , only upper and lower letter cases are supported).

##Bryan Guner (Full-stack software developer)

Portfolio <a target="_blank" rel="noopener noreferrer"target="_blank" rel="noopener noreferrer"href="https://github.com/bgoonz/resume-cv-portfolio-samples/blob/master/2021-resume/bryan-guner-resume-2021.pdf" download>Resume PDF Bryan's email Blog Linkedin AngelList GitHub bgoonz


-----------------------------------------------------

javascript-practice/-ALL-JS-Files/

let str = 'MIICWwIBAAKBgGEdLjFEFbegPZ2AwJWkalksXr7PzWL7wIc7pOFZxXwYPWtQxvANyceCwpkqbPLsfEx7nqxAris2hYOdeN1OTFqvTyNmVuzbUPcXShn6ZoDCB30voHkeu4F3cUw5RQEUDdLscSnv4HMxHam5qgl6vXoumVNHbjyKA5UtAnfjAgMBAAECgYAmjEyvpZTxRJvwjxDi1VaZevFI0Hd4WPH9PAGgqdnH84vGXnAGFj1WikqKYcqKMQW2kdjAsWwH9D9FfrkIcDDHdZ9XuGSGkFzWtOwajWMQl7qNV1hZ288gdpIQQMOTLDgauZY6pw1cV7h4v316qJB8knQGoBNpJCfTYQJBAKV1ctsJq0Zg4QumD2hyODepP3LfLeaQsERLqVAWeuOuTY5mK5gIwsSqvcSVfY7Ze1FWIsApNFRv67azKcJPwsCQQCNlyApZFJEVNY70Er7Uu5NL9t4CYJJC9uVVkoEHEY6d7sVslqa0vP2q0zXx9YedbMBvQjxXIbY0waXUy63FvoBGJAkB3OTJWUjVgzDY1Br5wu2Yu59NjKVKLWzCsu1gaCNBfhVDX7SyIyC9EYKRfUAoQxwsmPWPyQ9QVG4WKcPZJAkBRheAotPCBE2RLHHfvpiStnMhX0UXdVyaJp5tcZ6wYV61ohyBvCOkYhUxBJzeIGrVZcvLZSLeUzXoqRPpxQxAkEAkdCZXF0gHahpZgF5y0wWcqf9ECRT1E4Hv8bk3Mf0Exp2aW34JeI6I7Xqd1NV4I9H7prQ8m3y39lFwWO8PmQ'; console.log( str.indexOf( 'HEY' ) ); console.log( 0 ); //--- --------------------------------------------------------------------------------> //---------------------------------------(NEXT:)-------------------------------------> //--- --------------------------------------------------------------------------------> // Write a function alternatingCaps that accepts a sentence string as an argument. The function should // return the sentence where words alternate between lowercase and uppercase. let alternatingCaps = sentence => { let words = sentence.split( ' ' ); let newWords = []; for ( let i = 0; i < words.length; i++ ) { let word = words[ i ]; if ( i % 2 === 0 ) { newWords.push( word.toLowerCase() ); } else { newWords.push( word.toUpperCase() ); } } return newWords.join( ' ' ); }; console.log( alternatingCaps( "take them to school" ) ); // 'take THEM to SCHOOL' console.log( alternatingCaps( "What did ThEy EAT before?" ) ); // 'what DID they EAT before?' //--- --------------------------------------------------------------------------------> //---------------------------------------(NEXT:)-------------------------------------> //--- --------------------------------------------------------------------------------> // Write a function averageOfFour(num1, num2, num3, num4) that accepts four numbers as arguments. The // function should return the average of all four numbers. let averageOfFour = ( num1, num2, num3, num4 ) => { let sum = num1 + num2 + num3 + num4; return sum / 4; }; console.log( averageOfFour( 10, 4, 12, 3 ) ); // 7.25 console.log( averageOfFour( -20, 50, 4, 21 ) ); // 13.75 console.log( averageOfFour( 10, 4, 12, 3 ) ); // 7.25 console.log( averageOfFour( 5, 5, 3, 7 ) ); // 5 //--- --------------------------------------------------------------------------------> //---------------------------------------(NEXT:)-------------------------------------> //--- --------------------------------------------------------------------------------> // Write a function average that accepts three numbers as arguments. The function should return the // average of the three numbers. let average = ( num1, num2, num3 ) => ( num1 + num2 + num3 ) / 3; console.log( average( 3, 10, 8 ) ); // 7 console.log( average( 10, 5, 12 ) ); // 9 console.log( average( 6, 20, 40 ) ); // 22 //--- --------------------------------------------------------------------------------> //---------------------------------------(NEXT:)-------------------------------------> //--- --------------------------------------------------------------------------------> // Write a function bleepVowels that accepts a string as an argument. The function should return // a new string where all vowels are replaced with *s. Vowels are the letters a, e, i, o, u. let bleepVowels = str => { let vowels = [ "a", "e", "i", "o", "u" ]; let bleeped = ""; for ( let char of str ) { if ( vowels.includes( char ) ) { bleeped += ""; } else { bleeped += char; } } return bleeped; }; console.log( bleepVowels( "skateboard" ) ); // 'sktb**rd' console.log( bleepVowels( "slipper" ) ); // 'slppr' console.log( bleepVowels( "range" ) ); // 'rng*' console.log( bleepVowels( "brisk morning" ) ); // 'brsk mrnng' console.log( false ); // false console.log( !true ); // false console.log( !false ); // true console.log( !!true ); // true console.log( false && false ); // false console.log( false && true ); // false console.log( true && false ); // false console.log( true && true ); // true console.log( false || false ); // false console.log( false || true ); // true console.log( true || false ); // true console.log( true || true ); // true console.log( !false || false ); // true console.log( false || ( true && true ) ); // true console.log( false || !( true && true ) ); // false console.log( !true && ( true ) ); // false //--- --------------------------------------------------------------------------------> //---------------------------------------(NEXT:)-------------------------------------> //--- --------------------------------------------------------------------------------> // Write a function caseChange that accepts a string and a boolean as arguments. The function should // return the uppercase version of the string if the boolean is true. The function should return the // lowercase version of the string if the boolean is false. let caseChange = ( str, shouldUpperCase ) => { if ( shouldUpperCase ) { return str.toUpperCase(); } else { return str.toLowerCase(); } }; console.log( caseChange( "Super", true ) ); // 'SUPER' console.log( caseChange( "Super", false ) ); // 'super' console.log( caseChange( "tAmBourine", true ) ); // 'TAMBOURINE' console.log( caseChange( "tAmBourine", false ) ); // 'tambourine' //--- --------------------------------------------------------------------------------> //---------------------------------------(NEXT:)-------------------------------------> //--- --------------------------------------------------------------------------------> // Write a function censorE that accepts a string as an argument. The function should return the a new // version of string where all characters that are 'e's are replaced with ''s. let censorE = str => { let newStr = ''; for ( let char of str ) { if ( char === 'e' ) { newStr += ''; } else { newStr += char; } } return newStr; }; console.log( censorE( "speedy" ) ); // 'sp**dy' console.log( censorE( "pending" ) ); // 'pnding' console.log( censorE( "scene" ) ); // 'scn' console.log( censorE( "heat" ) ); // 'h*at' //--- --------------------------------------------------------------------------------> //---------------------------------------(NEXT:)-------------------------------------> //--- --------------------------------------------------------------------------------> // Write a function chooseDivisibles(numbers, target) that accepts an array of numbers and a // target number as arguments. The function should return an array containing elements of the original // array that are divisible by the target. let chooseDivisibles = ( numbers, target ) => { let divisibles = []; for ( let num of numbers ) { if ( num % target === 0 ) { divisibles.push( num ); } } return divisibles; }; console.log( chooseDivisibles( [ 40, 7, 22, 20, 24 ], 4 ) ); // [40, 20, 24] console.log( chooseDivisibles( [ 9, 33, 8, 17 ], 3 ) ); // [9, 33] console.log( chooseDivisibles( [ 4, 25, 1000 ], 10 ) ); // [1000] //--- --------------------------------------------------------------------------------> //---------------------------------------(NEXT:)-------------------------------------> //--- --------------------------------------------------------------------------------> // Write a function commonElements that accepts two arrays as arguments. The function should return // a new array containing the elements that are found in both of the input arrays. The order of // the elements in the output array doesn't matter as long as the function returns the correct elements. let commonElements = ( array1, array2 ) => { let common = []; for ( let ele of array1 ) { if ( array2.includes( ele ) ) { common.push( ele ); } } return common; }; let arr1 = [ "a", "c", "d", "b" ]; let arr2 = [ "b", "a", "y" ]; console.log( commonElements( arr1, arr2 ) ); // ['a', 'b'] let arr3 = [ 4, 7 ]; let arr4 = [ 32, 7, 1, 4 ]; console.log( commonElements( arr3, arr4 ) ); // [4, 7] console.log( true === false ); // false console.log( false === false ); // true console.log( false !== true ); // true console.log( !true === false ); // true console.log( 2 + 3 === 5 ); // true console.log( 4 < 0 ); // false console.log( 10 >= 10 ); // true console.log( 10.3 >= 10 ); // true console.log( 100 / 2 === 50 ); // true console.log( 100 % 2 === 0 ); // true console.log( 11 % 2 === 0 ); // false console.log( 7.0 === 7 ); // true console.log( 13 % 5 > 0 ); // true console.log( "potato" === "potato" ); // true console.log( "Tomato" === "tomato" ); // false console.log( "42" === 42 ); // false console.log( 5 > 3 && 1 === 0 ); // false t //--- --------------------------------------------------------------------------------> //---------------------------------------(NEXT:)-------------------------------------> //--- --------------------------------------------------------------------------------> // Write a function contains(str1, str2) that accepts two strings as arguments. The function should // return a boolean indicating whether or not str2 is contained within str1. The function should // ignore any differences in capitalization. let contains = ( str1, str2 ) => { let lowerStr1 = str1.toLowerCase(); let lowerStr2 = str2.toLowerCase(); return lowerStr1.includes( lowerStr2 ); }; console.log( contains( "caterpillar", "pill" ) ); // true console.log( contains( "lion's share", "on" ) ); // true console.log( contains( "SORRY", "or" ) ); // true console.log( contains( "tangent", "gem" ) ); // false console.log( contains( "clock", "ok" ) ); // false //--- --------------------------------------------------------------------------------> //---------------------------------------(NEXT:)-------------------------------------> //--- --------------------------------------------------------------------------------> // Write a function countUp(max) that accepts a max number as an argument. The function should print // all numbers from 1 up to and including the max. The function doesn't need to return any value. It // should just print to the terminal. let countUp = max => { for ( let i = 1; i <= max; i++ ) { console.log( i ); } }; countUp( 5 ); // prints // 1 // 2 // 3 // 4 // 5 countUp( 3 ); // prints // 1 // 2 // 3 let phrase = "that's all folks"; console.log( phrase[ phrase.length ] ); // undefined console.log( phrase[ phrase.length - 1 ] ); // s console.log( phrase[ phrase.length - 2 ] ); // k const i = 9; const char = phrase[ i ]; console.log( char ); // l console.log( phrase.indexOf( char ) ); // 8 console.log( phrase.slice( 2, 8 ) ); // at's a console.log( "abcdefg".slice( 1, 3 ) ); // bc console.log( "abcdefg".slice( 2 ) ); // cdefg console.log( "abcdefg".slice( 4 ) ); // efg console.log( "abcdefg".slice( 2, -1 ) ); // cdef console.log( "abcdefg".slice( 2, -2 ) ); // cde //--- --------------------------------------------------------------------------------> //---------------------------------------(NEXT:)-------------------------------------> //--- --------------------------------------------------------------------------------> // Write a function named divByEither(num1, num2, max) that accepts three numbers as arguments. // The function should print out all positive numbers less than max that are divisible by num1 or num2. // The function doesn't need to return any value. It should just print to the terminal. let divByEither = ( num1, num2, max ) => { for ( let i = 1; i < max; i++ ) { if ( i % num1 === 0 || i % num2 === 0 ) { console.log( i ); } } }; divByEither( 4, 3, 16 ); // prints // 3 // 4 // 6 // 8 // 9 // 12 // 15 divByEither( 7, 5, 20 ); // prints // 5 // 7 // 10 // 14 // 15 //--- --------------------------------------------------------------------------------> //---------------------------------------(NEXT:)-------------------------------------> //--- --------------------------------------------------------------------------------> // Write a function divisibleRange(min, max, num) that accepts three numbers as arguments. The // function should print all numbers between min and max (exclusive) that are also divisible by // num. let divisibleRange = ( min, max, num ) => { for ( let i = min + 1; i < max; i++ ) { if ( i % num === 0 ) { console.log( i ); } } }; divisibleRange( 17, 40, 9 ); // prints // 18 // 27 // 36 divisibleRange( 10, 24, 4 ); // prints // 12 // 16 // 20 //--- --------------------------------------------------------------------------------> //---------------------------------------(NEXT:)-------------------------------------> //--- --------------------------------------------------------------------------------> // Write a function divisible(num1, num2) that accepts two numbers as arguments. The function should // return a boolean indicating whether or not num1 is divisible by num2. let divisible = ( num1, num2 ) => num1 % num2 === 0; // let divisible = function (num1, num2) { // if (num1 % num2 === 0) { // return true; // } else { // return false; // } // }; console.log( divisible( 12, 3 ) ); // true console.log( divisible( 12, 5 ) ); // false console.log( divisible( 60, 4 ) ); // true console.log( divisible( 60, 11 ) ); // false console.log( divisible( 21, 7 ) ); // true console.log( divisible( 21, 6 ) ); // false //--- --------------------------------------------------------------------------------> //---------------------------------------(NEXT:)-------------------------------------> //--- --------------------------------------------------------------------------------> // Write a function divisors that accepts a number as an argument. The function should return an // array containing all positive numbers that can divide into the argument. let divisors = n => { let numbers = []; for ( let i = 1; i <= n; i++ ) { if ( n % i === 0 ) { numbers.push( i ); } } return numbers; }; console.log( divisors( 15 ) ); // [1, 3, 5, 15] console.log( divisors( 7 ) ); // [1, 7] console.log( divisors( 24 ) ); // [1, 2, 3, 4, 6, 8, 12, 24] g //--- --------------------------------------------------------------------------------> //---------------------------------------(NEXT:)-------------------------------------> //--- --------------------------------------------------------------------------------> // Write a function endsInLy that accepts a string as an argument and returns a boolean indicating // whether or not the string ends in the substring 'ly'. let endsInLy = str => { let secondLast = str[ str.length - 2 ]; let last = str[ str.length - 1 ]; return secondLast === 'l' && last === 'y'; }; // let endsInLy = function (str) { // return str.endsWith('ly'); // }; console.log( endsInLy( "pretty" ) ); // false console.log( endsInLy( "instant" ) ); // false console.log( endsInLy( "analytic" ) ); // false console.log( endsInLy( "timidly" ) ); // true console.log( endsInLy( "fly" ) ); // true console.log( endsInLy( "gallantly" ) ); // true //--- --------------------------------------------------------------------------------> //---------------------------------------(NEXT:)-------------------------------------> //--- --------------------------------------------------------------------------------> // Write a function endsWithT that accepts a string as an argument. The function should return a // boolean indicating whether or not the string ends with the character 't'. let endsWithT = str => { let lastChar = str[ str.length - 1 ]; return lastChar === 't'; }; console.log( endsWithT( "smart" ) ); // true console.log( endsWithT( "racket" ) ); // true console.log( endsWithT( "taco" ) ); // false console.log( endsWithT( "boomerang" ) ); // false //--- --------------------------------------------------------------------------------> //---------------------------------------(NEXT:)-------------------------------------> //--- --------------------------------------------------------------------------------> // Write a function evens(max) that accepts a max number as an argument. The function should print // all positive even numbers that are less than the max. let evens = max => { for ( let i = 1; i < max; i++ ) { if ( i % 2 === 0 ) { console.log( i ); } } }; evens( 11 ); // prints // 2 // 4 // 6 // 8 // 10 evens( 8 ); // prints // 2 // 4 // 6 //--- --------------------------------------------------------------------------------> //---------------------------------------(NEXT:)-------------------------------------> //--- --------------------------------------------------------------------------------> // Write a function filterLongWords that accepts an array of strings as an argument. The function // should return a new array containing only the strings that are less than 5 characters long. let filterLongWords = words => { let chosenWords = []; for ( let word of words ) { if ( word.length < 5 ) { chosenWords.push( word ); } } return chosenWords; }; console.log( filterLongWords( [ "kale", "cat", "retro", "axe", "heirloom" ] ) ); // ['kale', 'cat', 'axe'] console.log( filterLongWords( [ "disrupt", "pour", "trade", "pic" ] ) ); // ['pour', 'pic'] //--- --------------------------------------------------------------------------------> //---------------------------------------(NEXT:)-------------------------------------> //--- --------------------------------------------------------------------------------> // Write a function named fiveMultiplesOf that accepts a number as an argument. The function should // print out the first five multiples of the given number. The function doesn't need to return any // value. It should just print to the terminal. let fiveMultiplesOf = num => { for ( let i = 1; i <= 5; i++ ) { console.log( i * num ); } }; fiveMultiplesOf( 7 ); // prints // 7 // 14 // 21 // 28 // 35 fiveMultiplesOf( 3 ); // prints // 3 // 6 // 9 // 12 // 15 //--- --------------------------------------------------------------------------------> //---------------------------------------(NEXT:)-------------------------------------> //--- --------------------------------------------------------------------------------> // Write a function fizzBuzz that accepts a max number as an argument. The function should // print all numbers less than or equal to max that are divisible by either 3 or 5 but not both 3 // and 5. The function doesn't need to return any value. It should just print to the terminal. let fizzBuzz = max => { for ( let i = 1; i <= max; i++ ) { if ( ( i % 3 === 0 || i % 5 === 0 ) && !( i % 3 === 0 && i % 5 === 0 ) ) { console.log( i ); } } }; fizzBuzz( 18 ); // prints // 3 // 5 // 6 // 9 // 10 // 12 // 18 fizzBuzz( 33 ); // prints // 3 // 5 // 6 // 9 // 10 // 12 // 18 // 20 // 21 // 24 // 25 // 27 // 33 let movie = 'Fight Club'; let views = 4; console.log( I watched ${ movie } about ${ views } number of times ); //--- --------------------------------------------------------------------------------> //---------------------------------------(NEXT:)-------------------------------------> //--- --------------------------------------------------------------------------------> // Write a function funnySound that accepts two strings as arguments. The function should return a // new string containing the first three characters of both strings concatenated together. // You can assume that the arguments are both at least three characters long. let funnySound = ( str1, str2 ) => str1.slice( 0, 3 ) + str2.slice( 0, 3 ); console.log( funnySound( "tiger", "spoon" ) ); // 'tigspo' console.log( funnySound( "computer", "phone" ) ); // 'compho' console.log( funnySound( "skate", "bottle" ) ); // 'skabot' console.log( funnySound( "frog", "ashtray" ) ); // 'froash' console.log( 'hello world' ); //--- --------------------------------------------------------------------------------> //---------------------------------------(NEXT:)-------------------------------------> //--- --------------------------------------------------------------------------------> // Write a function half that accepts a number as an argument. The function should return half of the // number. let half = n => n / 2; console.log( half( 8 ) ); // 4 console.log( half( 15 ) ); // 7.5 console.log( half( 90 ) ); // 45 gi //--- --------------------------------------------------------------------------------> //---------------------------------------(NEXT:)-------------------------------------> //--- --------------------------------------------------------------------------------> // Write a function inRange(min, max, n) that accepts three numbers as arguments. The function should // return a boolean indicating if n is between min and max inclusive. let inRange = ( min, max, n ) => n >= min && n <= max; console.log( inRange( 5, 13, 8 ) ); // true console.log( inRange( 5, 13, 29 ) ); // false console.log( inRange( 100, 125, 100 ) ); // true console.log( inRange( 100, 125, 99 ) ); // false console.log( inRange( 40, 45, 44 ) ); // true console.log( inRange( 40, 45, 45 ) ); // true console.log( inRange( 40, 45, 46 ) ); // false //--- --------------------------------------------------------------------------------> //---------------------------------------(NEXT:)-------------------------------------> //--- --------------------------------------------------------------------------------> // Write a function isDivBy4 that accepts a number as an argument. The function should return a // boolean indicating whether or not the number is divisible by 4. let isDivBy4 = num => { if ( num % 4 === 0 ) { return true; } else { return false; } }; // let isDivBy4 = function (num) { // return num % 4 === 0; // }; console.log( isDivBy4( 8 ) ); // true console.log( isDivBy4( 12 ) ); // true console.log( isDivBy4( 24 ) ); // true console.log( isDivBy4( 9 ) ); // false console.log( isDivBy4( 10 ) ); // false //--- --------------------------------------------------------------------------------> //---------------------------------------(NEXT:)-------------------------------------> //--- --------------------------------------------------------------------------------> // Write a function isLong that accepts a string as an argument. The function should return a boolean // indicating whether or not the string is longer than 5 characters let isLong = ( { length } ) => length > 5; // let isLong = function (str) { // if (str.length > 5) { // return true; // } else { // return false; // } // }; console.log( isLong( "pie" ) ); // false console.log( isLong( "kite" ) ); // false console.log( isLong( "kitty" ) ); // false console.log( isLong( "telescope" ) ); // true console.log( isLong( "thermometer" ) ); // true console.log( isLong( "restaurant" ) ); // true //--- --------------------------------------------------------------------------------> //---------------------------------------(NEXT:)-------------------------------------> //--- --------------------------------------------------------------------------------> // Write a function keepItQuiet that accepts a string as an argument. The function should return the // lowercase version of the string with 3 periods added to the end of it. let keepItQuiet = str => ${ str.toLowerCase() }...; console.log( keepItQuiet( "HOORAY" ) ); // 'hooray...' console.log( keepItQuiet( "Doggo" ) ); // 'doggo...' console.log( keepItQuiet( "WHAT?!?!" ) ); // 'what?!?!...' //--- --------------------------------------------------------------------------------> //---------------------------------------(NEXT:)-------------------------------------> //--- --------------------------------------------------------------------------------> // Write a function larger that accepts two numbers as arguments. The function should return the // larger number. let larger = ( num1, num2 ) => { if ( num1 > num2 ) { return num1; } else { return num2; } }; console.log( larger( 256, 400 ) ); // 400 console.log( larger( 31, 4 ) ); // 31 console.log( larger( -6, 7 ) ); // 7 console.log( larger( 11.3, 11.2 ) ); // 11.3 console.log( larger( -10, -3 ) ); // -3 //--- --------------------------------------------------------------------------------> //---------------------------------------(NEXT:)-------------------------------------> //--- --------------------------------------------------------------------------------> // Write a function lengthiestWord that accepts a sentence string as an argument. The function should // return the longest word of the sentence. If there is a tie, return the word that appears later // in the sentence. let lengthiestWord = sentence => { let words = sentence.split( ' ' ); let longest = words[ 0 ]; // pretty for ( let i = 1; i < words.length; i++ ) { let word = words[ i ]; if ( word.length >= longest.length ) { longest = word; } } return longest; }; console.log( lengthiestWord( "I am pretty hungry" ) ); // 'hungry' console.log( lengthiestWord( "we should think outside of the box" ) ); // 'outside' console.log( lengthiestWord( "down the rabbit hole" ) ); // 'rabbit' console.log( lengthiestWord( "simmer down" ) ); // 'simmer' //--- --------------------------------------------------------------------------------> //---------------------------------------(NEXT:)-------------------------------------> //--- --------------------------------------------------------------------------------> // Write a function longer that accepts two strings as arguments. The function should return the // string that is longer. If the strings have the same length, then return the first string. let longer = ( str1, str2 ) => { if ( str1.length >= str2.length ) { return str1; } else { return str2; } }; console.log( longer( "drum", "piranha" ) ); // 'piranha' console.log( longer( "basket", "fork" ) ); // 'basket' console.log( longer( "flannel", "sustainable" ) ); // 'sustainable' console.log( longer( "disrupt", "ability" ) ); // 'disrupt' console.log( longer( "bird", "shoe" ) ); // 'bird' //--- --------------------------------------------------------------------------------> //---------------------------------------(NEXT:)-------------------------------------> //--- --------------------------------------------------------------------------------> // Write a function makeAcronym that accepts a sentence string as an argument. The function should // return a string containing the first character of each word in the sentence. let makeAcronym = sentence => { let words = sentence.split( ' ' ); let acronym = ''; for ( let word of words ) { acronym += word[ 0 ]; } return acronym.toUpperCase(); }; console.log( makeAcronym( "New York" ) ); // NY console.log( makeAcronym( "same stuff different day" ) ); // SSDD console.log( makeAcronym( "Laugh out loud" ) ); // LOL console.log( makeAcronym( "don't over think stuff" ) ); // DOTS //--- --------------------------------------------------------------------------------> //---------------------------------------(NEXT:)-------------------------------------> //--- --------------------------------------------------------------------------------> // Write a function makeMatrix(m, n, value) that accepts three arguments. The function should return // a 2-dimensional array of height m and width n that contains the value as every element. let makeMatrix = ( m, n, value ) => { let matrix = []; for ( let i = 0; i < m; i++ ) { let row = []; for ( let j = 0; j < n; j++ ) { row.push( value ); } matrix.push( row ); } return matrix; }; console.log( makeMatrix( 3, 5, null ) ); // [ // [ null, null, null, null, null ], // [ null, null, null, null, null ], // [ null, null, null, null, null ] // ] console.log( makeMatrix( 4, 2, "x" ) ); // [ // [ 'x', 'x' ], // [ 'x', 'x' ], // [ 'x', 'x' ], // [ 'x', 'x' ] // ] console.log( makeMatrix( 2, 2, 0 ) ); // [ // [ 0, 0 ], // [ 0, 0 ] // ] //--- --------------------------------------------------------------------------------> //---------------------------------------(NEXT:)-------------------------------------> //--- --------------------------------------------------------------------------------> // Write a function maximum that accepts an array of numbers as an argument. The function should // return the largest number of the array. If the array is empty, then the function should return null. let maximum = numbers => { if ( numbers.length === 0 ) { return null; } let currentMax = numbers[ 0 ]; for ( let i = 1; i < numbers.length; i++ ) { if ( numbers[ i ] > currentMax ) { currentMax = numbers[ i ]; } } return currentMax; }; console.log( maximum( [ 5, 6, 3, 7 ] ) ); // 7 console.log( maximum( [ 17, 15, 19, 11, 2 ] ) ); // 19 console.log( maximum( [] ) ); // null //--- --------------------------------------------------------------------------------> //---------------------------------------(NEXT:)-------------------------------------> //--- --------------------------------------------------------------------------------> // Write a function minToMax(min, max) that accepts two numbers as arguments. The function should // print all numbers from min to max inclusive. The function doesn't need to return any value. It // should just print to the terminal. let minToMax = ( min, max ) => { for ( let i = min; i <= max; i++ ) { console.log( i ); } }; minToMax( 5, 9 ); // prints // 5 // 6 // 7 // 8 // 9 minToMax( 11, 13 ); // prints // 11 // 12 // 13 //--- --------------------------------------------------------------------------------> //---------------------------------------(NEXT:)-------------------------------------> //--- --------------------------------------------------------------------------------> // Write a function named noOhs that accepts a string as an argument. The functions should print the // characters of the string one by one except the character 'o'. The function doesn't need to return // any value. It should just print to the terminal. let noOhs = str => { for ( let char of str ) { if ( char !== 'o' ) { console.log( char ); } } }; noOhs( "code" ); // prints // c // d // e noOhs( "school" ); // prints // s // c // h // l //--- --------------------------------------------------------------------------------> //---------------------------------------(NEXT:)-------------------------------------> //--- --------------------------------------------------------------------------------> // Write a function numOdds that accepts an array of numbers as an argument. The function should // return a number representing the count of odd elements in the array. function numOdds( numbers ) { let count = 0; for ( let i = 0; i < numbers.length; { if () {} }( numbers[ i ] % 2 ) === 1 ) { count += 1; } } return count; }; console.log( numOdds( [ 4, 7, 2, 5, 9 ] ) ); // 3 console.log( numOdds( [ 11, 31, 58, 99, 21, 60 ] ) ); // 4 console.log( numOdds( [ 100, 40, 4 ] ) ); // 0 //--- --------------------------------------------------------------------------------> //---------------------------------------(NEXT:)-------------------------------------> //--- --------------------------------------------------------------------------------> // Write a function numberChange that accepts a number as an argument. The function should return // half the number if it is even. The function should return double the number if it is odd. let numberChange = n => { if ( n % 2 === 0 ) { return n / 2; } else { return n * 2; } }; console.log( numberChange( 6 ) ); // 3 console.log( numberChange( 7 ) ); // 14 console.log( numberChange( 16 ) ); // 8 console.log( numberChange( 21 ) ); // 42 console.log( 2 + 3 ); // 5 console.log( 10 - 15 ); // -5 console.log( 4 + 1 - 5 ); // 0 console.log( 4 * 3 ); // 12 console.log( 7 / 2 ); // 3.5 console.log( 4 + 2 * 3 ); // 10 console.log( ( 4 + 2 ) * 3 ); // 18 console.log( 5 % 2 ); // 1 console.log( 6 % 2 ); // 0 console.log( 7 % 2 ); // 1 console.log( 8 % 2 ); // 0 console.log( 19 % 8 ); // 3 console.log( 24 % 8 ); // 0 console.log( 7 % 4 ); // 3 console.log( 4 % 7 ); // 4 console.log( 5 + ( 10 % 5 ) ); // 5 console.log( ( 5 + 10 ) % 5 ); // 0 //--- --------------------------------------------------------------------------------> //---------------------------------------(NEXT:)-------------------------------------> //--- --------------------------------------------------------------------------------> // Write a function numberRange(min, max, step) that accepts three numbers as arguments, min, // max, and step. The function should return all numbers between min and max at step intervals. // min and max are inclusive. let numberRange = ( min, max, step ) => { let range = []; for ( let i = min; i <= max; i += step ) { range.push( i ); } return range; }; console.log( numberRange( 10, 40, 5 ) ); // [10, 15, 20, 25, 30, 35, 40] console.log( numberRange( 14, 24, 3 ) ); // [14, 17, 20, 23] console.log( numberRange( 8, 35, 6 ) ); // [8, 14, 20, 26, 32] //--- --------------------------------------------------------------------------------> //---------------------------------------(NEXT:)-------------------------------------> //--- --------------------------------------------------------------------------------> // Write a function named oddSum(max) that accepts a max number as an argument. The function should // return the total sum of all odd numbers from 1 to the max, inclusive. // // For example, oddSum(10) should return 25 because 1 + 3 + 5 + 7 + 9 = 25 let oddSum = max => { let sum = 0; for ( let i = 1; i <= max; i++ ) { if ( i % 2 === 1 ) { sum += i; } } return sum; }; console.log( oddSum( 10 ) ); // 25 console.log( oddSum( 5 ) ); // 9 let word = "bye"; console.log( ${ word } felicia ); // 'bye felicia' console.log( word ); // 'bye' let num = 10; num = num * 2; console.log( num ); // 20 let bottlesOfBeer = 99; let around = bottlesOfBeer - 1; console.log( around ); // 98 console.log( bottlesOfBeer ); // 99 //--- --------------------------------------------------------------------------------> //---------------------------------------(NEXT:)-------------------------------------> //--- --------------------------------------------------------------------------------> // Write a function oneOrNone that accepts two booleans as arguments. The function should return true // if exactly one of the arguments is true. If BOTH arguments are true, then it should return false. let oneOrNone = ( val1, val2 ) => { if ( ( val1 || val2 ) && !( val1 && val2 ) ) { return true; } else { return false; } }; console.log( oneOrNone( false, false ) ); // false console.log( oneOrNone( true, false ) ); // true console.log( oneOrNone( false, true ) ); // true console.log( oneOrNone( true, true ) ); // false //--- --------------------------------------------------------------------------------> //---------------------------------------(NEXT:)-------------------------------------> //--- --------------------------------------------------------------------------------> // Write a function oneToFour that prints all whole numbers from one to four, inclusive. The function // takes in no arguments and doesn't need to return any value. It should just print to the terminal. let oneToFour = () => { for ( let i = 1; i <= 4; i++ ) { console.log( i ); } }; oneToFour(); // prints // 1 // 2 // 3 // 4 i t // snippet 1-0 let qty = 38; if ( qty > 30 && qty % 5 === 4 ) { console.log( "swish" ); } else { console.log( "swoosh" ); // prints } if ( qty > 0 ) { console.log( "pos" ); // prints } // snippet 1-1 let a = "celery"; let b = "SQUASH"; if ( a === a.toUpperCase() ) { console.log( "alpha" ); } if ( b === b.toUpperCase() ) { console.log( "beta" ); // prints } // snippet 1-2 let number = 9; if ( number > 4 ) { console.log( "ding" ); // prints } else if ( number % 3 === 0 ) { console.log( "dong" ); } // snippet 1-3 let z = 12; if ( z > 10 ) { console.log( "vroom" ); // prints } if ( z % 3 === 0 ) { console.log( "skrrt" ); // prints } //--- --------------------------------------------------------------------------------> //---------------------------------------(NEXT:)-------------------------------------> //--- --------------------------------------------------------------------------------> // Write a function pairPrint that accepts an array as an argument. The function should print // all unique pairs of elements in the array. The function doesn't need to return any value. It // should just print to the terminal.

let pairPrint = function ( array ) { for ( let i = 0; i < array.length; i++ ) { for ( let j = i + 1; j < array.length; j++ ) { console.log( array[ i ] + ' - ' + array[ j ] ); } } };

pairPrint( [ "artichoke", "broccoli", "carrot", "daikon" ] ); // prints // artichoke - broccoli // artichoke - carrot // artichoke - daikon // broccoli - carrot // broccoli - daikon // carrot - daikon

pairPrint( [ "apple", "banana", "clementine" ] ); // prints // apple - banana // apple - clementine // banana - clementine

//--- --------------------------------------------------------------------------------> //---------------------------------------(NEXT:)-------------------------------------> //--- --------------------------------------------------------------------------------> // Write a function parity that accepts a number as an argument. The function should return the // string 'even' if the number is even. It should return the string 'odd' if the number is odd. let parity = function ( num ) { if ( num % 2 === 0 ) { return 'even'; } else { return 'odd'; } }; console.log( parity( 5 ) ); // 'odd' console.log( parity( 7 ) ); // 'odd' console.log( parity( 13 ) ); // 'odd' console.log( parity( 32 ) ); // 'even' console.log( parity( 10 ) ); // 'even' console.log( parity( 602348 ) ); // 'even' //--- --------------------------------------------------------------------------------> //---------------------------------------(NEXT:)-------------------------------------> //--- --------------------------------------------------------------------------------> // Write a function print2d that accepts a two-dimensional array as an argument. The function // should print all inner elements of the array.

let print2d = function ( array ) { for ( let i = 0; i < array.length; i++ ) { let subarray = array[ i ]; for ( let j = 0; j < subarray.length; j++ ) { console.log( subarray[ j ] ); } } };

let array1 = [ [ "a", "b", "c", "d" ], [ "e", "f" ], [ "g", "h", "i" ], ]; print2d( array1 ); // prints // a // b // c // d // e // f // g // h // i

let array2 = [ [ 9, 3, 4 ], [ 11 ], [ 42, 100 ] ]; print2d( array2 ); // prints // 9 // 3 // 4 // 11 // 42 // 100

//--- --------------------------------------------------------------------------------> //---------------------------------------(NEXT:)-------------------------------------> //--- --------------------------------------------------------------------------------> /// Write a function printCombinationsthat accepts two arrays as arguments. The function should // print all combinations of the elements generated by taking an element from the first array and // and an element from the second array. The function doesn't need to return any value. It // should just print to the terminal.

let printCombinations = function ( array1, array2 ) { for ( let i = 0; i < array1.length; i++ ) { let ele1 = array1[ i ];

for ( let j = 0; j < array2.length; j++ ) {
  let ele2 = array2[ j ];
  console.log( ele1, ele2 );
}

} };

let colors = [ "gray", "cream", "cyan" ]; let clothes = [ "shirt", "flannel" ]; printCombinations( colors, clothes ); // prints // gray shirt // gray flannel // cream shirt // cream flannel // cyan shirt // cyan flannel

printCombinations( [ "hot", "cold" ], [ "soup", "tea" ] ); // prints // hot soup // hot tea // cold soup // cold tea

//--- --------------------------------------------------------------------------------> //---------------------------------------(NEXT:)-------------------------------------> //--- --------------------------------------------------------------------------------> // Write a function named productUpTo(max) that accepts a max number as an argument. The function // should return the total product of all whole numbers from 1 to the max, inclusive. A product is a // number obtained from multiplying numbers together. // // For example, productUpTo(4) should return 24 because 1 * 2 * 3 * 4 = 24 let productUpTo = function ( max ) { let product = 1; for ( let i = 1; i <= max; i++ ) { product *= i; } return product; }; console.log( productUpTo( 4 ) ); // 24 console.log( productUpTo( 5 ) ); // 120 console.log( productUpTo( 7 ) ); // 5040 let word = "suspension bridge"; console.log( word[ 4 ] ); // e console.log( word.length > 5 && word[ 0 ] === "d" ); // false console.log( word.length > 5 && word[ 0 ] === "s" ); // true console.log( word.indexOf( "o" ) > -1 ); // true console.log( word.indexOf( "z" ) > -1 ); // false let str = "foggy"; console.log( str[ 2 + 1 ] ); // g console.log( str[ str.length - 1 ] ); // y str = " day"; console.log( str ); // ' day' console.log( str.length ); // 4 console.log( str.indexOf( "ogg" ) ); // -1 //--- --------------------------------------------------------------------------------> //---------------------------------------(NEXT:)-------------------------------------> //--- --------------------------------------------------------------------------------> // Write a function raisePower(base, exponent) that accepts two numbers, base and exponent. The // function should return base raised to the exponent power. // // For example, raisePower(2, 5) should return 32 because 2 * 2 * 2 * 2 * 2 = 32 // For example, raisePower(4, 3) should return 64 because 4 * 4 * 4 = 64 let raisePower = function ( base, exponent ) { let product = 1; for ( let i = 1; i <= exponent; i++ ) { product *= base; } return product; }; console.log( raisePower( 2, 5 ) ); // 32 console.log( raisePower( 4, 3 ) ); // 64 console.log( raisePower( 10, 4 ) ); // 10000 console.log( raisePower( 7, 2 ) ); // 49 //--- --------------------------------------------------------------------------------> //---------------------------------------(NEXT:)-------------------------------------> //--- --------------------------------------------------------------------------------> // Write a function removeCapitals that accepts a string as an argument. The function should return a // new version of the string with all capital letters removed. let removeCapitals = function ( str ) { let newStr = ''; for ( let i = 0; i < str.length; { let char = str[ i ]; if ( char === char.toLowerCase() ) { newStr += char; } } return newStr; }; console.log( removeCapitals( "fOrEver" ) ); // 'frver' console.log( removeCapitals( "raiNCoat" ) ); // 'raioat' console.log( removeCapitals( "cElLAr Door" ) ); // 'clr oor' //--- --------------------------------------------------------------------------------> //---------------------------------------(NEXT:)-------------------------------------> //--- --------------------------------------------------------------------------------> // Write a function removeDupes that accepts an array as an argument. The function should return a // new array where each element only appears once. let removeDupes = function ( array ) { let uniques = []; for ( let i = 0; i < array.length; { let ele = array[ i ]; if ( !uniques.includes( ele ) ) { uniques.push( ele ); } } return uniques; }; console.log( removeDupes( [ "x", "y", "y", "x", "z" ] ) ); // ['x', 'y', 'z'] console.log( removeDupes( [ false, false, true, false ] ) ); // [false, true] console.log( removeDupes( [ 42, 5, 7, 42, 7, 3, 7, 7 ] ) ); // [42, 5, 7, 3] //--- --------------------------------------------------------------------------------> //---------------------------------------(NEXT:)-------------------------------------> //--- --------------------------------------------------------------------------------> // Write a function removeFirstVowel that accepts a string as an argument. The function should return // the string with it's first vowel removed. let removeFirstVowel = function ( str ) { let vowels = 'aeiou'; for ( let i = 0; i < str.length; { let char = str[ i ]; if ( vowels.includes( char ) ) { return str.slice( 0, i ) + str.slice( i + 1 ); } } return str; }; console.log( removeFirstVowel( "volcano" ) ); // 'vlcano' console.log( removeFirstVowel( "celery" ) ); // 'clery' console.log( removeFirstVowel( "juice" ) ); // 'jice' console.log( removeFirstVowel( "bridge" ) ); // 'brdge' console.log( removeFirstVowel( "try" ) ); // 'try' //--- --------------------------------------------------------------------------------> //---------------------------------------(NEXT:)-------------------------------------> //--- --------------------------------------------------------------------------------> // Write a function removeShortWords that accepts a sentence string as an argument. The function // should return a new sentence where all of the words shorter than 4 characters are removed. let removeShortWords = function ( sentence ) { let words = sentence.split( ' ' ); let chosenWords = []; for ( let i = 0; i < words.length; { let word = words[ i ]; if ( word.length >= 4 ) { chosenWords.push( word ); } } return chosenWords.join( ' ' ); }; console.log( removeShortWords( "knock on the door will you" ) ); // 'knock door will' console.log( removeShortWords( "a terrible plan" ) ); // 'terrible plan' console.log( removeShortWords( "run faster that way" ) ); // 'faster that' //--- --------------------------------------------------------------------------------> //---------------------------------------(NEXT:)-------------------------------------> //--- --------------------------------------------------------------------------------> // Write a function removeVowels that accepts a string as an argument. The function should return // a version of the string where all vowels are removed. let removeVowels = function ( str ) { let newStr = ''; let vowels = 'aeiou'; for ( let i = 0; i < str.length; { let char = str[ i ]; if ( !vowels.includes( char ) ) { newStr += char; } } return newStr; }; console.log( removeVowels( "jello" ) ); // jll console.log( removeVowels( "sensitivity" ) ); // snstvty console.log( removeVowels( "cellar door" ) ); // cllr dr //--- --------------------------------------------------------------------------------> //---------------------------------------(NEXT:)-------------------------------------> //--- --------------------------------------------------------------------------------> // Write a function reverseArray that accepts an array as an argument. The function should return a // array containing the elements of the original array in reverse order. let reverseArray1 = function ( array ) { let reversed = []; for ( let i = array.length - 1; i >= 0; i-- ) { reversed.push( array[ i ] ); } return reversed; }; console.log( reverseArray1( [ "zero", "one", "two", "three" ] ) ); // ['three', 'two', 'one', 'zero'] console.log( reverseArray1( [ 7, 1, 8 ] ) ); // [8, 1, 7] let reverseArray2 = function ( array ) { let reversed = []; for ( let i = 0; i < array.length; { reversed.unshift( array[ i ] ); } return reversed; }; console.log( reverseArray2( [ "zero", "one", "two", "three" ] ) ); // ['three', 'two', 'one', 'zero'] console.log( reverseArray2( [ 7, 1, 8 ] ) ); // [8, 1, 7] //--- --------------------------------------------------------------------------------> //---------------------------------------(NEXT:)-------------------------------------> //--- --------------------------------------------------------------------------------> // Write a function reverseIterate that accepts a string as an argument. The function should print // the characters of the string one by one, in reverse order. The function doesn't need to return any // value. It should just print to the terminal. let reverseIterate = function ( str ) { for ( let i = str.length - 1; i >= 0; i-- ) { console.log( str[ i ] ); } }; reverseIterate( "carrot" ); // prints // t // o // r // r // a // c reverseIterate( "box" ); // prints // x // o // b

                    //--- -------------------------------------------------------------------------------->
                    //---------------------------------------(NEXT:)------------------------------------->
                    //--- -------------------------------------------------------------------------------->
                    // Write a function `shortenLongWords` that accepts a sentence string as an argument. The function
                    // should return the same sentence where words longer than 4 characters have their vowels removed.
                    let removeVowels = function ( str ) {
                        let newStr = '';
                        let vowels = 'aeiou';
                        for ( let i = 0; i < str.length; {
                            let char = str[ i ];
                            if ( !vowels.includes( char ) ) {
                              newStr += char;
                            }
                          }
                          return newStr;
                        };
                        let shortenLongWords = function ( sentence ) {
                            let words = sentence.split( ' ' );
                            let newWords = [];
                            for ( let i = 0; i < words.length; {
                                let word = words[ i ];
                                if ( word.length > 4 ) {
                                  let noVowels = removeVowels( word );
                                  newWords.push( noVowels );
                                } else {
                                  // leave it the same
                                  newWords.push( word );
                                }
                              }
                              return newWords.join( ' ' );
                            };
                            console.log( shortenLongWords( "they are very noble people" ) ); // 'they are very nbl ppl'
                            console.log( shortenLongWords( "stick with it" ) ); // 'stck with it'
                            console.log( shortenLongWords( "ballerina, you must have seen her" ) ); // 'bllrna, you must have seen her
                            console.log( "promenade" [ 3 ] ); // m
                            console.log( "tiger" [ 1 ] ); // i
                            console.log( "wheel".length ); // 5
                            console.log( "wheel".length - 1 ); // 4
                            console.log( "noMAD".toUpperCase() ); // NOMAD
                            console.log( "hey programmers" [ 2 ] === "y" ); // true
                            console.log( "volleyball".length > 20 ); // false
                            console.log( "treasure".indexOf( "r" ) ); // 1
                            console.log( "treasure".indexOf( "e" ) ); // 2
                            console.log( "web" [ 5 ] ); // undefined
                            console.log( "red".indexOf( "x" ) ); // -1
                            console.log( "red".indexOf( "R" ) ); // -1
                            // snippet 0-1
                            let greet = function () {
                              console.log( "hey" );
                              console.log( "programmers" );
                            };
                            let whistle = function () {
                              console.log( "doot" );
                            };
                            console.log( "first" );
                            console.log( "second" );
                            greet();
                            console.log( "third" );
                            console.log( "fourth" );
                            whistle();
                            // first
                            // second
                            // hey
                            // programmers
                            // third
                            // fourth
                            // doot
                            // snippet 0-2
                            let howMany = function () {
                              return 42;
                            };
                            console.log( howMany );
                            console.log( howMany() );
                            const theAnswer = howMany();
                            console.log( theAnswer );
                            let howMuch = function () {
                              5;
                            };
                            console.log( howMuch() );
                            // [Function: howMany]
                            // 42
                            // 42
                            // undefined
                            // snippet 0-3
                            let average = function ( num1, num2 ) {
                              console.log( "calculating..." );
                              return ( num1 + num2 ) / 2;
                            };
                            console.log( average( 5, 10 ) );
                            console.log( average( 20, 26 ) );
                            console.log( average( 50, 100 ) + 2 );
                            let a = 21 + 3;
                            let b = 20;
                            let n = average( a, b );
                            console.log( average( n, 18 ) );
                            // calculating...
                            // 7.5
                            // calculating...
                            // 23
                            // calculating...
                            // 77
                            // calculating...
                            // calculating...
                            // 20
                            // snippet 0-4
                            let exclaim = function ( str ) {
                              let capitalized = str.toUpperCase();
                              return capitalized + "!!";
                            };
                            let result = exclaim( "potato" );
                            console.log( result );
                            console.log( result.length );
                            console.log( result[ 0 ] );
                            console.log( result[ result.length - 1 ] );
                            // POTATO!!
                            // 8
                            // P
                            // !
                            // snippet 1
                            console.log( "hello" );
                            for ( let i = 0; i < 5; i++ ) {
                              console.log( "code" );
                            }
                            console.log( "goodbye" );
                            hello
                            code
                            code
                            code
                            code
                            code
                            goodbye
                            // snippet 1
                            for ( let i = 1; i <= 4; i++ ) {
                              for ( let j = 1; j <= 3; j++ ) {
                                console.log( i, j );
                              }
                            }
                            // 1 1
                            // 1 2
                            // 1 3
                            // 2 1
                            // 2 2
                            // 2 3
                            // 3 1
                            // 3 2
                            // 3 3
                            // 4 1
                            // 4 2
                            // 4 3
                            // snippet 2
                            console.log( "hi" );
                            for ( let i = 3; i <= 7; i++ ) {
                              console.log( "program" );
                              console.log( i );
                            }
                            console.log( "bye" );
                            // hi
                            // program
                            // 3
                            // program
                            // 4
                            // program
                            // 5
                            // program
                            // 6
                            // program
                            // 7
                            // bye
                            // snippet 2
                            for ( let n = 0; n < 2; n++ ) {
                              console.log( "n=" + n );
                              for ( let m = 0; m < 5; m++ ) {
                                console.log( "   m=" + m );
                              }
                              console.log( "n=" + n );
                            }
                            // n=0
                            //    m=0
                            //    m=1
                            //    m=2
                            //    m=3
                            //    m=4
                            // n=0
                            // n=1
                            //    m=0
                            //    m=1
                            //    m=2
                            //    m=3
                            //    m=4
                            // n=1
                            // snippet 3
                            let foo = function () {
                              for ( let num = 10; num > 0; num -= 2 ) {
                                console.log( num );
                              }
                            };
                            console.log( "begin" );
                            foo();
                            console.log( "end" );
                            foo();
                            // begin
                            // 10
                            // 8
                            // 6
                            // 4
                            // 2
                            // end
                            // 10
                            // 8
                            // 6
                            // 4
                            // 2
                            // snippet 3
                            let friends = [ "philip", "abby", "phelipe", "simcha" ];
                            for ( let i = 0; i < friends.length; {
                                for ( let j = 0; j < friends.length; {
                                    console.log( friends[ i ], friends[ j ] );
                                  }
                                }
                                // philip philip
                                // philip abby
                                // philip phelipe
                                // philip simcha
                                // abby philip
                                // abby abby
                                // abby phelipe
                                // abby simcha
                                // phelipe philip
                                // phelipe abby
                                // phelipe phelipe
                                // phelipe simcha
                                // simcha philip
                                // simcha abby
                                // simcha phelipe
                                // simcha simcha
                                // snippet 4
                                let word = "street";
                                for ( let i = 0; i < word.length; {
                                    console.log( i );
                                    console.log( word[ i ] );
                                  }
                                  // 0
                                  // s
                                  // 1
                                  // t
                                  // 2
                                  // r
                                  // 3
                                  // e
                                  // 4
                                  // e
                                  // 5
                                  // t
                                  // snippet 4
                                  let locations = [ "flatbush", "williamsburg", "bushwick", "greenpoint" ];
                                  for ( let i = 0; i < locations.length; {
                                      for ( let j = i + 1; j < locations.length; {
                                          console.log( locations[ i ], locations[ j ] );
                                        }
                                      }
                                      // flatbush williamsburg
                                      // flatbush bushwick
                                      // flatbush greenpoint
                                      // williamsburg bushwick
                                      // williamsburg greenpoint
                                      // bushwick greenpoint
                                      // snippet 5
                                      let total = 0; // 10
                                      for ( let i = 1; i < 5; i++ ) {
                                        total += i;
                                        console.log( total );
                                      }
                                      console.log( "grand total: " + total );
                                      // 1
                                      // 3
                                      // 6
                                      // 10
                                      // grand total: 10
                                      // snippet 5
                                      let colors = [ "red", "purple", "orange" ];
                                      for ( let i = 0; i < colors.length; {
                                          let colorStr = colors[ i ];
                                          console.log( colorStr );
                                          for ( let j = 0; j < colorStr.length; {
                                              let char = colorStr[ j ];
                                              console.log( char );
                                            }
                                          }
                                          // red
                                          // r
                                          // e
                                          // d
                                          // purple
                                          // p
                                          // u
                                          // r
                                          // p
                                          // l
                                          // e
                                          // orange
                                          // o
                                          // r
                                          // a
                                          // n
                                          // g
                                          // e
                                          //--- -------------------------------------------------------------------------------->
                                          //---------------------------------------(NEXT:)------------------------------------->
                                          //--- -------------------------------------------------------------------------------->
                                          // Write a function `spam` that accepts a 2D array as an argument. The array contains pairs as elements.
                                          // The first element of every pair is a number and the second element is a word. The function should
                                          // return a string containing the words repeated the specified number of times. See the examples.
                                          let spam = function ( pairs ) {
                                              let words = [];
                                              for ( let i = 0; i < pairs.length; {
                                                  let pair = pairs[ i ];
                                                  let word = pair[ 0 ];
                                                  let num = pair[ 1 ];
                                                  for ( let j = 0; j < num; {
                                                      words.push( word );
                                                    }
                                                  }
                                                  return words.join( ' ' );
                                                };
                                                let array1 = [
                                                  [ "hi", 3 ],
                                                  [ "bye", 2 ],
                                                ]; console.log( spam( array1 ) ); // 'hi hi hi bye bye'
                                                let array2 = [
                                                  [ "cat", 1 ],
                                                  [ "dog", 2 ],
                                                  [ "bird", 4 ],
                                                ]; console.log( spam( array2 ) ); // 'cat dog dog bird bird bird bird'
                                                //--- -------------------------------------------------------------------------------->
                                                //---------------------------------------(NEXT:)------------------------------------->
                                                //--- -------------------------------------------------------------------------------->
                                                // Write a function `startsWithR` that accepts a string as an argument and returns a boolean indicating
                                                // whether or not the string starts with 'r' or 'R'.
                                                let startsWithR = function ( str ) {
                                                  return str[ 0 ] === 'r' || str[ 0 ] === 'R';
                                                }; console.log( startsWithR( "roger that" ) ); // true
                                                console.log( startsWithR( "Row, row, row your boat" ) ); // true
                                                console.log( startsWithR( "slip" ) ); // false
                                                console.log( startsWithR( "Taxicab" ) ); // false
                                                //--- -------------------------------------------------------------------------------->
                                                //---------------------------------------(NEXT:)------------------------------------->
                                                //--- -------------------------------------------------------------------------------->
                                                // Write a function `stayPositive` that accepts an array of numbers as an argument. The function should
                                                // return an array containing only the positive numbers.
                                                let stayPositive = function ( numbers ) {
                                                    let positives = [];
                                                    for ( let i = 0; i < numbers.length; {
                                                        if ( numbers[ i ] > 0 ) {
                                                          positives.push( numbers[ i ] );
                                                        }
                                                      }
                                                      return positives;
                                                    };
                                                    console.log( stayPositive( [ 10, -4, 3, 6 ] ) ); // [10, 3, 6]
                                                    console.log( stayPositive( [ -5, 11, -40, 30.3, -2 ] ) ); // [11, 30.3]
                                                    console.log( stayPositive( [ -11, -30 ] ) ); // []
                                                    console.log( "river" + "town" );
                                                    console.log( "cat" + "dog" );
                                                    console.log( "New" + " York" );
                                                    console.log( "runner's knee" + "!" );
                                                    console.log( "man" + "bear" + "pig" );
                                                    //--- -------------------------------------------------------------------------------->
                                                    //---------------------------------------(NEXT:)------------------------------------->
                                                    //--- -------------------------------------------------------------------------------->
                                                    // Write a function `stringIterate` that accepts a string as an argument. The function should print out
                                                    // each character of the string, one by one. The function doesn't need to return any value. It should
                                                    // just print to the terminal.
                                                    let stringIterate = function ( string ) {
                                                        for ( let i = 0; i < string.length; {
                                                            console.log( string[ i ] );
                                                          }
                                                        };
                                                        stringIterate( "celery" );
                                                        // prints
                                                        //  c
                                                        //  e
                                                        //  l
                                                        //  e
                                                        //  r
                                                        //  y
                                                        stringIterate( "hat" );
                                                        // prints
                                                        //  h
                                                        //  a
                                                        //  t
                                                        //--- -------------------------------------------------------------------------------->
                                                        //---------------------------------------(NEXT:)------------------------------------->
                                                        //--- -------------------------------------------------------------------------------->
                                                        // Write a function named `stringRepeater(str, num)` that accepts a string and a number as arguments.
                                                        // The function should return a new string consisting of the `str` repeated `num` number of times.
                                                        let stringRepeater = function ( str, num ) {
                                                          let repeatedStr = '';
                                                          for ( let i = 1; i <= num; i++ ) {
                                                            repeatedStr += str
                                                          }
                                                          return repeatedStr;
                                                        };
                                                        console.log( stringRepeater( "q", 4 ) ); // 'qqqq'
                                                        console.log( stringRepeater( "go", 2 ) ); // 'gogo'
                                                        console.log( stringRepeater( "tac", 3 ) ); // 'tactactac'
                                                        //--- -------------------------------------------------------------------------------->
                                                        //---------------------------------------(NEXT:)------------------------------------->
                                                        //--- -------------------------------------------------------------------------------->
                                                        // Write a function `stringSize` that accepts a string as an argument. The function should return the
                                                        // string 'small' if the argument is shorter than 5 characters, 'medium' if it is exactly 5 characters, and
                                                        // 'large' if it is longer than 5 characters.
                                                        let stringSize = function ( str ) {
                                                          if ( str.length < 5 ) {
                                                            return 'small';
                                                          } else if ( str.length > 5 ) {
                                                            return 'large';
                                                          } else {
                                                            return 'medium';
                                                          }
                                                        };
                                                        console.log( stringSize( "cat" ) ); // 'small'
                                                        console.log( stringSize( "bell" ) ); // 'small'
                                                        console.log( stringSize( "ready" ) ); // 'medium'
                                                        console.log( stringSize( "shirt" ) ); // 'medium'
                                                        console.log( stringSize( "shallow" ) ); // 'large'
                                                        console.log( stringSize( "intelligence" ) ); // 'large'
                                                        //--- -------------------------------------------------------------------------------->
                                                        //---------------------------------------(NEXT:)------------------------------------->
                                                        //--- -------------------------------------------------------------------------------->
                                                        // Write a function `stringsToLengths` that accepts an array of strings as an argument. The function
                                                        // should return a new array containing the lengths of the elements of the original array.
                                                        let stringsToLengths = function ( words ) {
                                                            let lengths = [];
                                                            for ( let i = 0; i < words.length; {
                                                                lengths.push( words[ i ].length );
                                                              }
                                                              return lengths;
                                                            };
                                                            console.log( stringsToLengths( [ "belly", "echo", "irony", "pickled" ] ) );
                                                            // [5, 4, 5, 7]
                                                            console.log( stringsToLengths( [ "on", "off", "handmade" ] ) );
                                                            // [2, 3, 8]
                                                            //--- -------------------------------------------------------------------------------->
                                                            //---------------------------------------(NEXT:)------------------------------------->
                                                            //--- -------------------------------------------------------------------------------->
                                                            // Write a function named `sumUpTo(max)` that accepts a max number as an argument. The function should
                                                            // return the total sum of all whole numbers from 1 to the max, inclusive.
                                                            //
                                                            // For example, sumUpTo(4) should return 10 because 1 + 2 + 3 + 4 = 10.
                                                            let sumUpTo = function ( max ) {
                                                              let sum = 0;
                                                              for ( let i = 1; i <= max; i++ ) {
                                                                sum += i
                                                              }
                                                              return sum;
                                                            };
                                                            console.log( sumUpTo( 4 ) ); // 10
                                                            console.log( sumUpTo( 5 ) ); // 15
                                                            console.log( sumUpTo( 2 ) ); // 3
                                                            console.log( 'coffee' );
                                                            let qty = 15 % 4;
                                                            console.log( qty ); // 3
                                                            let num = 38 + 3;
                                                            num++;
                                                            console.log( num + " is a great number" ); // '42 is a great number'
                                                            let isNumEven = num % 2 === 0;
                                                            console.log( num + " is even? " + isNumEven ); // '42 is even? true'
                                                            let isQtyEven = qty % 2 === 0;
                                                            console.log( qty + " is even? " + isQtyEven ); // '3 is even? false'
                                                            glet longStr = "AIICXAIBAAKBgQCuw0YyucjI9bf7yRhIkyg4Ru6kYU7O6fIn2JoFDzCZNkzDdsuXFGh6BXNvbu8uZUT289ERzYP1QjryMEKWzcbtsioyQApL7AgOZyFc3JJ7wvupHhIj2sqxJNtpAh7HQFG08rYh2Pb3HwOm83rbTomM6LnnjooGcoDeuWkuPqXsRlwIDAQABAoGAeQkbPBR5n9y2QLaEjcDGv7dVpFiMGHMaZZVDX34rZPy1EkZNZqlQU0jopLVvLyLESMh9A7gKhqoyMAbgZPpdb0CvniTJPpKYk24mLBeym8rBMW3XBmKk1xIOcJPGXMxeJW61jxPg6doah0aCIjf8n0Z8t8B81kLFojpECQQDzlCp0Nzka3AVZVPdBuuPg0fzeV8ugpiPEp6wQLjIMDFqYtGoAOEy4JpkmkK7zwsQsHZ8jbOtqIFdRLPrvAkEAruU321Ie1CnYCHX4Q79vLcDeWOUpdzEHp2uzDIfzP1gv7RIktGgSZWKhrnNWdeH4Y0CFb9lu6TQYJwNJvug2QJBANX0m3Uds9P9pLbQlI9WWmAtYqIZrsBElcAjOgAik0uOfawholNiw5B3ADvIYqPkLW4dGk1dO6zxW8ZF83MdMCQHGfhxLuFgsOBSfF7Bj4UX6T9FGhUGSXiqUsd06E2mMRLAjWUUUw82DLwucxMrSsV4z1aN57asC8YuQ9FkCQGirlVCt4ccXeGLCHcCsI8AYQJFRzbMs381M16jEpnaKUGrtdbMW018gWJ0EoD4tS2YZpr1hEbtiOkPJaaTKQ";
                                                            if ( longStr.indexOf( 'coDe' ) > -1 ) {
                                                              console.log( 'FOUND' );
                                                            } else {
                                                              console.log( 'NOT FOUND' );
                                                            }
                                                            //--- -------------------------------------------------------------------------------->
                                                            //---------------------------------------(NEXT:)------------------------------------->
                                                            //--- -------------------------------------------------------------------------------->
                                                            // Write a function `totalProduct(array)` that accepts a 2D array of numbers. The function should return
                                                            // the total product of all numbers in the array.
                                                            let totalProduct = function ( array ) {
                                                                let product = 1;
                                                                for ( let i = 0; i < array.length; {
                                                                    let subarray = array[ i ];
                                                                    for ( let j = 0; j < subarray.length; {
                                                                        product *= subarray[ j ];
                                                                      }
                                                                    }
                                                                    return product;
                                                                  };
                                                                  let array1 = [
                                                                    [ 3, 5, 2 ],
                                                                    [ 6, 2 ],
                                                                  ]; console.log( totalProduct( array1 ) ); // 360
                                                                  let array2 = [
                                                                    [ 4, 6 ],
                                                                    [ 2, 3 ],
                                                                    [ 1, 2 ],
                                                                  ]; console.log( totalProduct( array2 ) ); // 288
                                                                  //--- -------------------------------------------------------------------------------->
                                                                  //---------------------------------------(NEXT:)------------------------------------->
                                                                  //--- -------------------------------------------------------------------------------->
                                                                  // Write a function `total` that accepts an array of numbers as an argument. The function should return
                                                                  // the total sum of all elements of the array.
                                                                  let total = function ( numbers ) {
                                                                      let sum = 0;
                                                                      for ( let i = 0; i < numbers.length; {
                                                                          sum += numbers[ i ];
                                                                        }
                                                                        return sum;
                                                                      };
                                                                      console.log( total( [ 3, 2, 8 ] ) ); // 13
                                                                      console.log( total( [ -5, 7, 4, 6 ] ) ); // 12
                                                                      console.log( total( [ 7 ] ) ); // 7
                                                                      console.log( total( [] ) ); // 0
                                                                      let apple;
                                                                      console.log( apple ); // undefined
                                                                      apple = 5;
                                                                      console.log( apple ); // 5
                                                                      apple + 1;
                                                                      console.log( apple ); // 5
                                                                      apple += 1;
                                                                      console.log( apple ); // 6
                                                                      let banana = apple;
                                                                      console.log( banana ); // 6
                                                                      banana = banana / 2;
                                                                      console.log( banana ); // 3
                                                                      console.log( apple ); // 6
                                                                      //--- -------------------------------------------------------------------------------->
                                                                      //---------------------------------------(NEXT:)------------------------------------->
                                                                      //--- -------------------------------------------------------------------------------->
                                                                      // Write a function `twoSumPairs(numbers, target)` that accepts an array of numbers and a target number
                                                                      // as arguments. The function should return a 2D array containing all unique pairs of elements that
                                                                      // sum to the target.
                                                                      let twoSumPairs = function ( numbers, target ) {
                                                                          let pairs = [];
                                                                          for ( let i = 0; i < numbers.length; {
                                                                              let num1 = numbers[ i ];
                                                                              for ( let j = i + 1; j < numbers.length; {
                                                                                  let num2 = numbers[ j ];
                                                                                  if ( num1 + num2 === target ) {
                                                                                    let pair = [ num1, num2 ];
                                                                                    pairs.push( pair );
                                                                                  }
                                                                                }
                                                                              }
                                                                              return pairs;
                                                                            }; console.log( twoSumPairs( [ 2, 3, 4, 6, 5 ], 8 ) ); // [ [2, 6], [3, 5] ]
                                                                            console.log( twoSumPairs( [ 10, 7, 4, 5, 2 ], 12 ) ); // [ [10, 2], [7, 5] ]
                                                                            console.log( twoSumPairs( [ 3, 9, 8 ], 11 ) ); // [ [3, 8] ]
                                                                            console.log( twoSumPairs( [ 3, 9, 8 ], 10 ) ); // [ ]
                                                                            //--- -------------------------------------------------------------------------------->
                                                                            //---------------------------------------(NEXT:)------------------------------------->
                                                                            //--- -------------------------------------------------------------------------------->
                                                                            // Write a function `twoSum(numbers, target)` that accepts an array of numbers and a target number
                                                                            // as an argument. The function should return a boolean indicating whether or not there exists a pair
                                                                            // of distinct elements in the array that sum to the target.
                                                                            let twoSum = function ( numbers, target ) {
                                                                                for ( let i = 0; i < numbers.length; {
                                                                                    for ( let j = i + 1; j < numbers.length; {
                                                                                        if ( numbers[ i ] + numbers[ j ] === target ) {
                                                                                          return true;
                                                                                        }
                                                                                      }
                                                                                    }
                                                                                    return false;
                                                                                  }; console.log( twoSum( [ 2, 3, 5, 9 ], 7 ) ); // true
                                                                                  console.log( twoSum( [ 2, 3, 5, 9 ], 4 ) ); // false
                                                                                  console.log( twoSum( [ 6, 3, 4 ], 10 ) ); // true
                                                                                  console.log( twoSum( [ 6, 5, 1 ], 10 ) ); // false
                                                                                  // snippet 2-1
                                                                                  let nonsense = "blog trust fund tattooed williamsburg poke roof party";
                                                                                  let hasOk = nonsense.indexOf( "ok" ) > -1;
                                                                                  if ( hasOk ) {
                                                                                    console.log( "yeet" ); // prints
                                                                                  } else if ( nonsense.length > 10 ) {
                                                                                    console.log( "yo" );
                                                                                  } else {
                                                                                    console.log( "no" );
                                                                                  }
                                                                                  let hasZoo = nonsense.indexOf( "zoo" ) > -1;
                                                                                  let hasFun = nonsense.indexOf( "fun" ) > -1;
                                                                                  if ( hasZoo && hasOk ) {
                                                                                    console.log( "cool" );
                                                                                  } else if ( hasOk ) {
                                                                                    console.log( "rad" ); // prints
                                                                                  } else if ( hasFun ) {
                                                                                    console.log( "dope" );
                                                                                  } else {
                                                                                    console.log( "nope" );
                                                                                  }
                                                                                  // snippet 2-2
                                                                                  let q = 25;
                                                                                  if ( q % 3 === 0 && q % 5 === 0 ) {
                                                                                    console.log( "both" );
                                                                                  } else if ( q % 3 === 0 || q % 5 == 0 ) {
                                                                                    console.log( "either" ); // prints
                                                                                  } else {
                                                                                    console.log( "neither" );
                                                                                  }
                                                                                  let r = 9;
                                                                                  if ( r % 3 === 0 && r % 5 === 0 ) {
                                                                                    console.log( "both" );
                                                                                  } else if ( r % 3 === 0 || r % 5 == 0 ) {
                                                                                    console.log( "either" ); // prints
                                                                                  } else {
                                                                                    console.log( "neither" );
                                                                                  }
                                                                                  let s = 15;
                                                                                  if ( s % 3 === 0 && s % 5 === 0 ) {
                                                                                    console.log( "both" ); // prints
                                                                                  } else if ( s % 3 === 0 || s % 5 == 0 ) {
                                                                                    console.log( "either" );
                                                                                  } else {
                                                                                    console.log( "neither" );
                                                                                  }
                                                                                  //--- -------------------------------------------------------------------------------->
                                                                                  //---------------------------------------(NEXT:)------------------------------------->
                                                                                  //--- -------------------------------------------------------------------------------->
                                                                                  // Write a function `wackyWord` that accepts two strings as arguments. The function should return a new
                                                                                  // string containing the first three characters of the first string concatenated with the last two
                                                                                  // character of the second string.
                                                                                  // You can assume that the first argument has a length of at least three and the second argument has a
                                                                                  // length of at least two.
                                                                                  let wackyWord = function ( str1, str2 ) {
                                                                                    return str1.slice( 0, 3 ) + str2.slice( -2 );
                                                                                  }; console.log( wackyWord( "very", "kindly" ) ); // 'verly'
                                                                                  console.log( wackyWord( "forever", "sick" ) ); // 'forck'
                                                                                  console.log( wackyWord( "cellar", "door" ) ); // 'celor'
                                                                                  console.log( wackyWord( "bagel", "sweep" ) ); // 'bagep'
                                                                                  console.log( 'alvin' ); console.log( 'z' );
                                                                                  //--- -------------------------------------------------------------------------------->
                                                                                  //---------------------------------------(NEXT:)------------------------------------->
                                                                                  //--- -------------------------------------------------------------------------------->
                                                                                  // Write a function `wordCount(sentence, targetWords)` that accepts a sentence string and an array of
                                                                                  // `targetWords`. The function should return a count of the number of words of the sentence that are
                                                                                  // in `targetWords`.
                                                                                  let wordCount = function ( sentence, targetWords ) {
                                                                                      let words = sentence.split( ' ' );
                                                                                      let count = 0;
                                                                                      for ( let i = 0; i < words.length; {
                                                                                          let word = words[ i ];
                                                                                          if ( targetWords.includes( word ) ) {
                                                                                            count++;
                                                                                          }
                                                                                        }
                                                                                        return count;
                                                                                      };
                                                                                      console.log( wordCount( "open the window please", [ "please", "open", "sorry" ] ) ); // 2
                                                                                      console.log( wordCount( "drive to the cinema", [ "the", "driver" ] ) ); // 1
                                                                                      console.log( wordCount( "can I have that can", [ "can", "I" ] ) ); // 3
                                                                                      //--- -------------------------------------------------------------------------------->
                                                                                      //---------------------------------------(NEXT:)------------------------------------->
                                                                                      //--- -------------------------------------------------------------------------------->
                                                                                      // Write a function `yourAverageFunction` that accepts an array of numbers as an argument. The
                                                                                      // function should return the average of all elements of the array. If the input array is empty,
                                                                                      // then the function should return null.
                                                                                      let yourAverageFunction = function ( nums ) {
                                                                                          if ( nums.length === 0 ) {
                                                                                            return null;
                                                                                          }
                                                                                          let sum = 0;
                                                                                          for ( let i = 0; i < nums.length; {
                                                                                              sum += nums[ i ];
                                                                                            }
                                                                                            return sum / nums.length;
                                                                                          };
                                                                                          console.log( yourAverageFunction( [ 5, 2, 7, 24 ] ) ); // 9.5
                                                                                          console.log( yourAverageFunction( [ 100, 6 ] ) ); // 53
                                                                                          console.log( yourAverageFunction( [ 31, 32, 40, 12, 33 ] ) ); // 29.6
                                                                                          console.log( yourAverageFunction( [] ) ); // null
                                                                                          let location = "Brooklyn, " + "NY";
                                                                                          console.log( location ); // 'Brooklyn, NY'
                                                                                          let quantity = 4 * 5 + 1;
                                                                                          console.log( quantity ); // 21
                                                                                          g it // snippet 0-1
                                                                                          if ( true ) {
                                                                                            console.log( "foo" ); // prints
                                                                                          }
                                                                                          if ( false ) {
                                                                                            console.log( "bar" );
                                                                                          }
                                                                                          // snippet 0-2
                                                                                          if ( false || false ) {
                                                                                            console.log( "boop" );
                                                                                          }
                                                                                          if ( true || false ) {
                                                                                            console.log( "beep" ); // prints
                                                                                          }
                                                                                          // snippet 0-3
                                                                                          let num = 40;
                                                                                          if ( num > 0 ) {
                                                                                            console.log( "zip" ); // prints
                                                                                          }
                                                                                          if ( num % 2 === 0 ) {
                                                                                            console.log( "zoop" ); // prints
                                                                                          }
                                                                                          // snippet 0-4
                                                                                          let word = "jeep";
                                                                                          if ( word[ 0 ] === "d" ) {
                                                                                            console.log( "yer" );
                                                                                          } else {
                                                                                            console.log( "nah" ); // prints
                                                                                          }
                                                                                          // snippet 0-5
                                                                                          let sentence = "roger that";
                                                                                          if ( sentence[ sentence.length - 1 ] === "t" ) {
                                                                                            console.log( "ends in t" ); // prints
                                                                                          } else {
                                                                                            console.log( "does not end in t" );
                                                                                          }
                                                                                          if ( sentence.length <= 4 ) {
                                                                                            console.log( "short" );
                                                                                          } else {
                                                                                            console.log( "long" ); // prints
                                                                                          }
                                                                                          //--- -------------------------------------------------------------------------------->
                                                                                          //---------------------------------------(NEXT:)------------------------------------->
                                                                                          //--- -------------------------------------------------------------------------------->
                                                                                          // Write a function `zipper` that accepts two arrays as arguments. The function should return a 2D
                                                                                          // array containing pairs of elements at the same indices.
                                                                                          let zipper = function ( arr1, arr2 ) {
                                                                                              let result = [];
                                                                                              for ( let i = 0; i < arr1.length; {
                                                                                                  let el1 = arr1[ i ];
                                                                                                  let el2 = arr2[ i ];
                                                                                                  let pair = [ el1, el2 ];
                                                                                                  result.push( pair );
                                                                                                }
                                                                                                return result;
                                                                                              };
                                                                                              let array1 = [ "a", "b", "c", "d" ];
                                                                                              let array2 = [ -1, -2, -3, -4 ];
                                                                                              console.log( zipper( array1, array2 ) );
                                                                                              // [
                                                                                              //   ['a', -1],
                                                                                              //   ['b', -2],
                                                                                              //   ['c', -3],
                                                                                              //   ['d', -4],
                                                                                              // ]
                                                                                              let array3 = [ "whisper", "talk", "shout" ];
                                                                                              let array4 = [ "quiet", "normal", "loud" ];
                                                                                              console.log( zipper( array3, array4 ) );
                                                                                              // [
                                                                                              //   ['whisper', 'quiet'],
                                                                                              //   ['talk', 'normal'],
                                                                                              //   ['shout', 'loud'],
                                                                                              // ]

let str = 'MIICWwIBAAKBgGEdLjFEFbegPZ2AwJWkalksXr7PzWL7wIc7pOFZxXwYPWtQxvANyceCwpkqbPLsfEx7nqxAris2hYOdeN1OTFqvTyNmVuzbUPcXShn6ZoDCB30voHkeu4F3cUw5RQEUDdLscSnv4HMxHam5qgl6vXoumVNHbjyKA5UtAnfjAgMBAAECgYAmjEyvpZTxRJvwjxDi1VaZevFI0Hd4WPH9PAGgqdnH84vGXnAGFj1WikqKYcqKMQW2kdjAsWwH9D9FfrkIcDDHdZ9XuGSGkFzWtOwajWMQl7qNV1hZ288gdpIQQMOTLDgauZY6pw1cV7h4v316qJB8knQGoBNpJCfTYQJBAKV1ctsJq0Zg4QumD2hyODepP3LfLeaQsERLqVAWeuOuTY5mK5gIwsSqvcSVfY7Ze1FWIsApNFRv67azKcJPwsCQQCNlyApZFJEVNY70Er7Uu5NL9t4CYJJC9uVVkoEHEY6d7sVslqa0vP2q0zXx9YedbMBvQjxXIbY0waXUy63FvoBGJAkB3OTJWUjVgzDY1Br5wu2Yu59NjKVKLWzCsu1gaCNBfhVDX7SyIyC9EYKRfUAoQxwsmPWPyQ9QVG4WKcPZJAkBRheAotPCBE2RLHHfvpiStnMhX0UXdVyaJp5tcZ6wYV61ohyBvCOkYhUxBJzeIGrVZcvLZSLeUzXoqRPpxQxAkEAkdCZXF0gHahpZgF5y0wWcqf9ECRT1E4Hv8bk3Mf0Exp2aW34JeI6I7Xqd1NV4I9H7prQ8m3y39lFwWO8PmQ';

console.log( str.indexOf( 'HEY' ) ); console.log( 0 ); // Write a function alternatingCaps that accepts a sentence string as an argument. The function should // return the sentence where words alternate between lowercase and uppercase.

let alternatingCaps = function ( sentence ) { let words = sentence.split( ' ' ); let newWords = [];

for ( let i = 0; i < words.length; i++ ) { let word = words[ i ]; if ( i % 2 === 0 ) { newWords.push( word.toLowerCase() ); } else { newWords.push( word.toUpperCase() ); } }

return newWords.join( ' ' ); };

console.log( alternatingCaps( "take them to school" ) ); // 'take THEM to SCHOOL' console.log( alternatingCaps( "What did ThEy EAT before?" ) ); // 'what DID they EAT before?' //APPEND-DIR.js const fs = require( 'fs' ); let cat = require( 'child_process' ).execSync( 'cat *' ).toString( 'UTF-8' );

fs.writeFile( 'output.md', cat, ( err ) => { if ( err ) throw err; } ); git // Write a function averageOfFour(num1, num2, num3, num4) that accepts four numbers as arguments. The // function should return the average of all four numbers.

let averageOfFour = function ( num1, num2, num3, num4 ) { let sum = num1 + num2 + num3 + num4; return sum / 4; };

console.log( averageOfFour( 10, 4, 12, 3 ) ); // 7.25 console.log( averageOfFour( -20, 50, 4, 21 ) ); // 13.75 console.log( averageOfFour( 10, 4, 12, 3 ) ); // 7.25 console.log( averageOfFour( 5, 5, 3, 7 ) ); // 5 // Write a function average that accepts three numbers as arguments. The function should return the // average of the three numbers.

let average = function ( num1, num2, num3 ) { return ( num1 + num2 + num3 ) / 3; };

console.log( average( 3, 10, 8 ) ); // 7 console.log( average( 10, 5, 12 ) ); // 9 console.log( average( 6, 20, 40 ) ); // 22 // Write a function bleepVowels that accepts a string as an argument. The function should return // a new string where all vowels are replaced with *s. Vowels are the letters a, e, i, o, u.

let bleepVowels = function ( str ) { let vowels = [ "a", "e", "i", "o", "u" ]; let bleeped = "";

for ( let i = 0; i < str.length; i++ ) { let char = str[ i ];

if ( vowels.indexOf( char ) > -1 ) {
  bleeped += "*";
} else {
  bleeped += char;
}

}

return bleeped; };

console.log( bleepVowels( "skateboard" ) ); // 'sktb**rd' console.log( bleepVowels( "slipper" ) ); // 'slppr' console.log( bleepVowels( "range" ) ); // 'rng' console.log( bleepVowels( "brisk morning" ) ); // 'brsk mrn*ng' console.log( false ); // false console.log( !true ); // false console.log( !false ); // true console.log( !!true ); // true

console.log( false && false ); // false console.log( false && true ); // false console.log( true && false ); // false console.log( true && true ); // true

console.log( false || false ); // false console.log( false || true ); // true console.log( true || false ); // true console.log( true || true ); // true

console.log( !false || false ); // true console.log( false || ( true && true ) ); // true console.log( false || !( true && true ) ); // false console.log( !true && ( true ) ); // false // Write a function caseChange that accepts a string and a boolean as arguments. The function should // return the uppercase version of the string if the boolean is true. The function should return the // lowercase version of the string if the boolean is false.

let caseChange = function ( str, shouldUpperCase ) { if ( shouldUpperCase ) { return str.toUpperCase(); } else { return str.toLowerCase(); } };

console.log( caseChange( "Super", true ) ); // 'SUPER' console.log( caseChange( "Super", false ) ); // 'super' console.log( caseChange( "tAmBourine", true ) ); // 'TAMBOURINE' console.log( caseChange( "tAmBourine", false ) ); // 'tambourine' // Write a function censorE that accepts a string as an argument. The function should return the a new // version of string where all characters that are 'e's are replaced with '*'s.

let censorE = function ( str ) { let newStr = '';

for ( let i = 0; i < str.length; i++ ) { let char = str[ i ];

if ( char === 'e' ) {
  newStr += '*';
} else {
  newStr += char;
}

}

return newStr; };

console.log( censorE( "speedy" ) ); // 'sp**dy' console.log( censorE( "pending" ) ); // 'pnding' console.log( censorE( "scene" ) ); // 'scn*' console.log( censorE( "heat" ) ); // 'h*at' // Write a function chooseDivisibles(numbers, target) that accepts an array of numbers and a // target number as arguments. The function should return an array containing elements of the original // array that are divisible by the target.

let chooseDivisibles = function ( numbers, target ) { let divisibles = [];

for ( let i = 0; i < numbers.length; i++ ) { let num = numbers[ i ];

if ( num % target === 0 ) {
  divisibles.push( num );
}

}

return divisibles; };

console.log( chooseDivisibles( [ 40, 7, 22, 20, 24 ], 4 ) ); // [40, 20, 24] console.log( chooseDivisibles( [ 9, 33, 8, 17 ], 3 ) ); // [9, 33] console.log( chooseDivisibles( [ 4, 25, 1000 ], 10 ) ); // [1000] // Write a function commonElements that accepts two arrays as arguments. The function should return // a new array containing the elements that are found in both of the input arrays. The order of // the elements in the output array doesn't matter as long as the function returns the correct elements.

let commonElements = function ( array1, array2 ) { let common = [];

for ( let i = 0; i < array1.length; i++ ) { let ele = array1[ i ];

if ( array2.includes( ele ) ) {
  common.push( ele );
}

}

return common; };

let arr1 = [ "a", "c", "d", "b" ]; let arr2 = [ "b", "a", "y" ]; console.log( commonElements( arr1, arr2 ) ); // ['a', 'b']

let arr3 = [ 4, 7 ]; let arr4 = [ 32, 7, 1, 4 ]; console.log( commonElements( arr3, arr4 ) ); // [4, 7] console.log( true === false ); // false console.log( false === false ); // true console.log( false !== true ); // true console.log( !true === false ); // true

console.log( 2 + 3 === 5 ); // true console.log( 4 < 0 ); // false console.log( 10 >= 10 ); // true console.log( 10.3 >= 10 ); // true

console.log( 100 / 2 === 50 ); // true console.log( 100 % 2 === 0 ); // true console.log( 11 % 2 === 0 ); // false console.log( 7.0 === 7 ); // true

console.log( 13 % 5 > 0 ); // true console.log( "potato" === "potato" ); // true console.log( "Tomato" === "tomato" ); // false console.log( "42" === 42 ); // false console.log( 5 > 3 && 1 === 0 ); // false t // Write a function contains(str1, str2) that accepts two strings as arguments. The function should // return a boolean indicating whether or not str2 is contained within str1. The function should // ignore any differences in capitalization.

let contains = function ( str1, str2 ) { let lowerStr1 = str1.toLowerCase(); let lowerStr2 = str2.toLowerCase(); return lowerStr1.indexOf( lowerStr2 ) > -1; };

console.log( contains( "caterpillar", "pill" ) ); // true console.log( contains( "lion's share", "on" ) ); // true console.log( contains( "SORRY", "or" ) ); // true console.log( contains( "tangent", "gem" ) ); // false console.log( contains( "clock", "ok" ) ); // false // Write a function countUp(max) that accepts a max number as an argument. The function should print // all numbers from 1 up to and including the max. The function doesn't need to return any value. It // should just print to the terminal.

let countUp = function ( max ) { for ( let i = 1; i <= max; i++ ) { console.log( i ); } };

countUp( 5 ); // prints // 1 // 2 // 3 // 4 // 5

countUp( 3 ); // prints // 1 // 2 // 3 let phrase = "that's all folks"; console.log( phrase[ phrase.length ] ); // undefined console.log( phrase[ phrase.length - 1 ] ); // s console.log( phrase[ phrase.length - 2 ] ); // k

const i = 9; const char = phrase[ i ]; console.log( char ); // l console.log( phrase.indexOf( char ) ); // 8 console.log( phrase.slice( 2, 8 ) ); // at's a

console.log( "abcdefg".slice( 1, 3 ) ); // bc console.log( "abcdefg".slice( 2 ) ); // cdefg console.log( "abcdefg".slice( 4 ) ); // efg

console.log( "abcdefg".slice( 2, -1 ) ); // cdef console.log( "abcdefg".slice( 2, -2 ) ); // cde // Write a function named divByEither(num1, num2, max) that accepts three numbers as arguments. // The function should print out all positive numbers less than max that are divisible by num1 or num2. // The function doesn't need to return any value. It should just print to the terminal.

let divByEither = function ( num1, num2, max ) { for ( let i = 1; i < max; i++ ) { if ( i % num1 === 0 || i % num2 === 0 ) { console.log( i ); } } };

divByEither( 4, 3, 16 ); // prints // 3 // 4 // 6 // 8 // 9 // 12 // 15

divByEither( 7, 5, 20 ); // prints // 5 // 7 // 10 // 14 // 15 // Write a function divisibleRange(min, max, num) that accepts three numbers as arguments. The // function should print all numbers between min and max (exclusive) that are also divisible by // num.

let divisibleRange = function ( min, max, num ) { for ( let i = min + 1; i < max; i++ ) { if ( i % num === 0 ) { console.log( i ); } } };

divisibleRange( 17, 40, 9 ); // prints // 18 // 27 // 36

divisibleRange( 10, 24, 4 ); // prints // 12 // 16 // 20 // Write a function divisible(num1, num2) that accepts two numbers as arguments. The function should // return a boolean indicating whether or not num1 is divisible by num2.

let divisible = function ( num1, num2 ) { return num1 % num2 === 0; };

// let divisible = function (num1, num2) { // if (num1 % num2 === 0) { // return true; // } else { // return false; // } // };

console.log( divisible( 12, 3 ) ); // true console.log( divisible( 12, 5 ) ); // false console.log( divisible( 60, 4 ) ); // true console.log( divisible( 60, 11 ) ); // false console.log( divisible( 21, 7 ) ); // true console.log( divisible( 21, 6 ) ); // false // Write a function divisors that accepts a number as an argument. The function should return an // array containing all positive numbers that can divide into the argument.

let divisors = function ( n ) { let numbers = [];

for ( let i = 1; i <= n; i++ ) { if ( n % i === 0 ) { numbers.push( i ); } }

return numbers; };

console.log( divisors( 15 ) ); // [1, 3, 5, 15] console.log( divisors( 7 ) ); // [1, 7] console.log( divisors( 24 ) ); // [1, 2, 3, 4, 6, 8, 12, 24] g // Write a function endsInLy that accepts a string as an argument and returns a boolean indicating // whether or not the string ends in the substring 'ly'.

let endsInLy = function ( str ) { let secondLast = str[ str.length - 2 ]; let last = str[ str.length - 1 ];

return secondLast === 'l' && last === 'y'; };

// let endsInLy = function (str) { // return str.endsWith('ly'); // };

console.log( endsInLy( "pretty" ) ); // false console.log( endsInLy( "instant" ) ); // false console.log( endsInLy( "analytic" ) ); // false console.log( endsInLy( "timidly" ) ); // true console.log( endsInLy( "fly" ) ); // true console.log( endsInLy( "gallantly" ) ); // true // Write a function endsWithT that accepts a string as an argument. The function should return a // boolean indicating whether or not the string ends with the character 't'.

let endsWithT = function ( str ) { let lastChar = str[ str.length - 1 ]; return lastChar === 't'; };

console.log( endsWithT( "smart" ) ); // true console.log( endsWithT( "racket" ) ); // true console.log( endsWithT( "taco" ) ); // false console.log( endsWithT( "boomerang" ) ); // false // Write a function evens(max) that accepts a max number as an argument. The function should print // all positive even numbers that are less than the max.

let evens = function ( max ) { for ( let i = 1; i < max; i++ ) { if ( i % 2 === 0 ) { console.log( i ); } } };

evens( 11 ); // prints // 2 // 4 // 6 // 8 // 10

evens( 8 ); // prints // 2 // 4 // 6 // Write a function filterLongWords that accepts an array of strings as an argument. The function // should return a new array containing only the strings that are less than 5 characters long.

let filterLongWords = function ( words ) { let chosenWords = [];

for ( let i = 0; i < words.length; i++ ) { let word = words[ i ];

if ( word.length < 5 ) {
  chosenWords.push( word );
}

}

return chosenWords; };

console.log( filterLongWords( [ "kale", "cat", "retro", "axe", "heirloom" ] ) ); // ['kale', 'cat', 'axe']

console.log( filterLongWords( [ "disrupt", "pour", "trade", "pic" ] ) ); // ['pour', 'pic'] // Write a function named fiveMultiplesOf that accepts a number as an argument. The function should // print out the first five multiples of the given number. The function doesn't need to return any // value. It should just print to the terminal.

let fiveMultiplesOf = function ( num ) { for ( let i = 1; i <= 5; i++ ) { console.log( i * num ); } };

fiveMultiplesOf( 7 ); // prints // 7 // 14 // 21 // 28 // 35

fiveMultiplesOf( 3 ); // prints // 3 // 6 // 9 // 12 // 15 // Write a function fizzBuzz that accepts a max number as an argument. The function should // print all numbers less than or equal to max that are divisible by either 3 or 5 but not both 3 // and 5. The function doesn't need to return any value. It should just print to the terminal.

let fizzBuzz = function ( max ) { for ( let i = 1; i <= max; i++ ) { if ( ( i % 3 === 0 || i % 5 === 0 ) && !( i % 3 === 0 && i % 5 === 0 ) ) { console.log( i ); } } };

fizzBuzz( 18 ); // prints // 3 // 5 // 6 // 9 // 10 // 12 // 18

fizzBuzz( 33 ); // prints // 3 // 5 // 6 // 9 // 10 // 12 // 18 // 20 // 21 // 24 // 25 // 27 // 33 let movie = 'Fight Club';

let views = 4;

console.log( 'I watched ' + movie + ' about ' + views + ' number of times' ); // Write a function funnySound that accepts two strings as arguments. The function should return a // new string containing the first three characters of both strings concatenated together.

// You can assume that the arguments are both at least three characters long.

let funnySound = function ( str1, str2 ) { return str1.slice( 0, 3 ) + str2.slice( 0, 3 ); };

console.log( funnySound( "tiger", "spoon" ) ); // 'tigspo' console.log( funnySound( "computer", "phone" ) ); // 'compho' console.log( funnySound( "skate", "bottle" ) ); // 'skabot' console.log( funnySound( "frog", "ashtray" ) ); // 'froash' console.log( 'hello world' ); // Write a function half that accepts a number as an argument. The function should return half of the // number.

let half = function ( n ) { return n / 2; };

console.log( half( 8 ) ); // 4 console.log( half( 15 ) ); // 7.5 console.log( half( 90 ) ); // 45 gi // Write a function inRange(min, max, n) that accepts three numbers as arguments. The function should // return a boolean indicating if n is between min and max inclusive.

let inRange = function ( min, max, n ) { return n >= min && n <= max; };

console.log( inRange( 5, 13, 8 ) ); // true console.log( inRange( 5, 13, 29 ) ); // false console.log( inRange( 100, 125, 100 ) ); // true console.log( inRange( 100, 125, 99 ) ); // false console.log( inRange( 40, 45, 44 ) ); // true console.log( inRange( 40, 45, 45 ) ); // true console.log( inRange( 40, 45, 46 ) ); // false // Write a function isDivBy4 that accepts a number as an argument. The function should return a // boolean indicating whether or not the number is divisible by 4.

let isDivBy4 = function ( num ) { if ( num % 4 === 0 ) { return true; } else { return false; } };

// let isDivBy4 = function (num) { // return num % 4 === 0; // };

console.log( isDivBy4( 8 ) ); // true console.log( isDivBy4( 12 ) ); // true console.log( isDivBy4( 24 ) ); // true console.log( isDivBy4( 9 ) ); // false console.log( isDivBy4( 10 ) ); // false // Write a function isLong that accepts a string as an argument. The function should return a boolean // indicating whether or not the string is longer than 5 characters

let isLong = function ( str ) { return str.length > 5; };

// let isLong = function (str) { // if (str.length > 5) { // return true; // } else { // return false; // } // };

console.log( isLong( "pie" ) ); // false console.log( isLong( "kite" ) ); // false console.log( isLong( "kitty" ) ); // false console.log( isLong( "telescope" ) ); // true console.log( isLong( "thermometer" ) ); // true console.log( isLong( "restaurant" ) ); // true // Write a function keepItQuiet that accepts a string as an argument. The function should return the // lowercase version of the string with 3 periods added to the end of it.

let keepItQuiet = function ( str ) { return str.toLowerCase() + '...'; };

console.log( keepItQuiet( "HOORAY" ) ); // 'hooray...' console.log( keepItQuiet( "Doggo" ) ); // 'doggo...' console.log( keepItQuiet( "WHAT?!?!" ) ); // 'what?!?!...' // Write a function larger that accepts two numbers as arguments. The function should return the // larger number.

let larger = function ( num1, num2 ) { if ( num1 > num2 ) { return num1; } else { return num2; } };

console.log( larger( 256, 400 ) ); // 400 console.log( larger( 31, 4 ) ); // 31 console.log( larger( -6, 7 ) ); // 7 console.log( larger( 11.3, 11.2 ) ); // 11.3 console.log( larger( -10, -3 ) ); // -3 // Write a function lengthiestWord that accepts a sentence string as an argument. The function should // return the longest word of the sentence. If there is a tie, return the word that appears later // in the sentence.

let lengthiestWord = function ( sentence ) { let words = sentence.split( ' ' ); let longest = words[ 0 ]; // pretty

for ( let i = 1; i < words.length; i++ ) { let word = words[ i ]; if ( word.length >= longest.length ) { longest = word; } }

return longest; };

console.log( lengthiestWord( "I am pretty hungry" ) ); // 'hungry' console.log( lengthiestWord( "we should think outside of the box" ) ); // 'outside' console.log( lengthiestWord( "down the rabbit hole" ) ); // 'rabbit' console.log( lengthiestWord( "simmer down" ) ); // 'simmer' // Write a function longer that accepts two strings as arguments. The function should return the // string that is longer. If the strings have the same length, then return the first string.

let longer = function ( str1, str2 ) { if ( str1.length >= str2.length ) { return str1; } else { return str2; } };

console.log( longer( "drum", "piranha" ) ); // 'piranha' console.log( longer( "basket", "fork" ) ); // 'basket' console.log( longer( "flannel", "sustainable" ) ); // 'sustainable' console.log( longer( "disrupt", "ability" ) ); // 'disrupt' console.log( longer( "bird", "shoe" ) ); // 'bird' // Write a function makeAcronym that accepts a sentence string as an argument. The function should // return a string containing the first character of each word in the sentence.

let makeAcronym = function ( sentence ) { let words = sentence.split( ' ' ); let acronym = '';

for ( let i = 0; i < words.length; i++ ) { let word = words[ i ]; acronym += word[ 0 ]; }

return acronym.toUpperCase(); };

console.log( makeAcronym( "New York" ) ); // NY console.log( makeAcronym( "same stuff different day" ) ); // SSDD console.log( makeAcronym( "Laugh out loud" ) ); // LOL console.log( makeAcronym( "don't over think stuff" ) ); // DOTS // Write a function makeMatrix(m, n, value) that accepts three arguments. The function should return // a 2-dimensional array of height m and width n that contains the value as every element.

let makeMatrix = function ( m, n, value ) { let matrix = [];

for ( let i = 0; i < m; i++ ) { let row = [];

for ( let j = 0; j < n; j++ ) {
  row.push( value );
}

matrix.push( row );

}

return matrix; };

console.log( makeMatrix( 3, 5, null ) ); // [ // [ null, null, null, null, null ], // [ null, null, null, null, null ], // [ null, null, null, null, null ] // ]

console.log( makeMatrix( 4, 2, "x" ) ); // [ // [ 'x', 'x' ], // [ 'x', 'x' ], // [ 'x', 'x' ], // [ 'x', 'x' ] // ]

console.log( makeMatrix( 2, 2, 0 ) ); // [ // [ 0, 0 ], // [ 0, 0 ] // ] // Write a function maximum that accepts an array of numbers as an argument. The function should // return the largest number of the array. If the array is empty, then the function should return null.

let maximum = function ( numbers ) { if ( numbers.length === 0 ) { return null; }

let currentMax = numbers[ 0 ]; for ( let i = 1; i < numbers.length; i++ ) { if ( numbers[ i ] > currentMax ) { currentMax = numbers[ i ]; } }

return currentMax; };

console.log( maximum( [ 5, 6, 3, 7 ] ) ); // 7 console.log( maximum( [ 17, 15, 19, 11, 2 ] ) ); // 19 console.log( maximum( [] ) ); // null // Write a function minToMax(min, max) that accepts two numbers as arguments. The function should // print all numbers from min to max inclusive. The function doesn't need to return any value. It // should just print to the terminal.

let minToMax = function ( min, max ) { for ( let i = min; i <= max; i++ ) { console.log( i ); } };

minToMax( 5, 9 ); // prints // 5 // 6 // 7 // 8 // 9

minToMax( 11, 13 ); // prints // 11 // 12 // 13 // Write a function named noOhs that accepts a string as an argument. The functions should print the // characters of the string one by one except the character 'o'. The function doesn't need to return // any value. It should just print to the terminal.

let noOhs = function ( str ) { for ( let i = 0; i < str.length; i++ ) { let char = str[ i ]; if ( char !== 'o' ) { console.log( char ); } } };

noOhs( "code" ); // prints // c // d // e

noOhs( "school" ); // prints // s // c // h // l // Write a function numOdds that accepts an array of numbers as an argument. The function should // return a number representing the count of odd elements in the array.

let numOdds = function ( numbers ) { let count = 0;

for ( let i = 0; i < numbers.length; i++ ) { if ( numbers[ i ] % 2 === 1 ) { count += 1; } }

return count; };

console.log( numOdds( [ 4, 7, 2, 5, 9 ] ) ); // 3 console.log( numOdds( [ 11, 31, 58, 99, 21, 60 ] ) ); // 4 console.log( numOdds( [ 100, 40, 4 ] ) ); // 0 // Write a function numberChange that accepts a number as an argument. The function should return // half the number if it is even. The function should return double the number if it is odd.

let numberChange = function ( n ) { if ( n % 2 === 0 ) { return n / 2; } else { return n * 2; } };

console.log( numberChange( 6 ) ); // 3 console.log( numberChange( 7 ) ); // 14 console.log( numberChange( 16 ) ); // 8 console.log( numberChange( 21 ) ); // 42 console.log( 2 + 3 ); // 5 console.log( 10 - 15 ); // -5 console.log( 4 + 1 - 5 ); // 0 console.log( 4 * 3 ); // 12

console.log( 7 / 2 ); // 3.5 console.log( 4 + 2 * 3 ); // 10 console.log( ( 4 + 2 ) * 3 ); // 18 console.log( 5 % 2 ); // 1

console.log( 6 % 2 ); // 0 console.log( 7 % 2 ); // 1 console.log( 8 % 2 ); // 0 console.log( 19 % 8 ); // 3

console.log( 24 % 8 ); // 0 console.log( 7 % 4 ); // 3 console.log( 4 % 7 ); // 4 console.log( 5 + ( 10 % 5 ) ); // 5 console.log( ( 5 + 10 ) % 5 ); // 0 // Write a function numberRange(min, max, step) that accepts three numbers as arguments, min, // max, and step. The function should return all numbers between min and max at step intervals. // min and max are inclusive.

let numberRange = function ( min, max, step ) { let range = [];

for ( let i = min; i <= max; i += step ) { range.push( i ); }

return range; };

console.log( numberRange( 10, 40, 5 ) ); // [10, 15, 20, 25, 30, 35, 40] console.log( numberRange( 14, 24, 3 ) ); // [14, 17, 20, 23] console.log( numberRange( 8, 35, 6 ) ); // [8, 14, 20, 26, 32] // Write a function named oddSum(max) that accepts a max number as an argument. The function should // return the total sum of all odd numbers from 1 to the max, inclusive. // // For example, oddSum(10) should return 25 because 1 + 3 + 5 + 7 + 9 = 25

let oddSum = function ( max ) { let sum = 0;

for ( let i = 1; i <= max; i++ ) { if ( i % 2 === 1 ) { sum += i; } }

return sum; };

console.log( oddSum( 10 ) ); // 25 console.log( oddSum( 5 ) ); // 9 let word = "bye"; console.log( ${word} felicia ); // 'bye felicia' console.log( word ); // 'bye'

let num = 10; num = num * 2; console.log( num ); // 20

let bottlesOfBeer = 99; let around = bottlesOfBeer - 1; console.log( around ); // 98 console.log( bottlesOfBeer ); // 99 // Write a function oneOrNone that accepts two booleans as arguments. The function should return true // if exactly one of the arguments is true. If BOTH arguments are true, then it should return false.

let oneOrNone = function ( val1, val2 ) { if ( ( val1 || val2 ) && !( val1 && val2 ) ) { return true; } else { return false; } };

console.log( oneOrNone( false, false ) ); // false console.log( oneOrNone( true, false ) ); // true console.log( oneOrNone( false, true ) ); // true console.log( oneOrNone( true, true ) ); // false // Write a function oneToFour that prints all whole numbers from one to four, inclusive. The function // takes in no arguments and doesn't need to return any value. It should just print to the terminal.

let oneToFour = function () { for ( let i = 1; i <= 4; i++ ) { console.log( i ); } };

oneToFour(); // prints // 1 // 2 // 3 // 4 let word = "bye"; console.log( word + " felicia" ); // 'bye felicia' console.log( word ); // 'bye'

let num = 10; num = num * 2; console.log( num ); // 20

let bottlesOfBeer = 99; let around = bottlesOfBeer - 1; console.log( around ); // 98 console.log( bottlesOfBeer ); // 99 // Write a function pairPrint that accepts an array as an argument. The function should print // all unique pairs of elements in the array. The function doesn't need to return any value. It // should just print to the terminal.

let pairPrint = function ( array ) { for ( let i = 0; i < array.length; i++ ) { for ( let j = i + 1; j < array.length; j++ ) { console.log( array[ i ] + ' - ' + array[ j ] ); } } };

pairPrint( [ "artichoke", "broccoli", "carrot", "daikon" ] ); // prints // artichoke - broccoli // artichoke - carrot // artichoke - daikon // broccoli - carrot // broccoli - daikon // carrot - daikon

pairPrint( [ "apple", "banana", "clementine" ] ); // prints // apple - banana // apple - clementine // banana - clementine // Write a function parity that accepts a number as an argument. The function should return the // string 'even' if the number is even. It should return the string 'odd' if the number is odd.

let parity = function ( num ) { if ( num % 2 === 0 ) { return 'even'; } else { return 'odd'; } };

console.log( parity( 5 ) ); // 'odd' console.log( parity( 7 ) ); // 'odd' console.log( parity( 13 ) ); // 'odd' console.log( parity( 32 ) ); // 'even' console.log( parity( 10 ) ); // 'even' console.log( parity( 602348 ) ); // 'even' // Write a function print2d that accepts a two-dimensional array as an argument. The function // should print all inner elements of the array.

let print2d = function ( array ) { for ( let i = 0; i < array.length; i++ ) { let subarray = array[ i ]; for ( let j = 0; j < subarray.length; j++ ) { console.log( subarray[ j ] ); } } };

let array1 = [ [ "a", "b", "c", "d" ], [ "e", "f" ], [ "g", "h", "i" ], ]; print2d( array1 ); // prints // a // b // c // d // e // f // g // h // i

let array2 = [ [ 9, 3, 4 ], [ 11 ], [ 42, 100 ] ]; print2d( array2 ); // prints // 9 // 3 // 4 // 11 // 42 // 100 // Write a function printCombinationsthat accepts two arrays as arguments. The function should // print all combinations of the elements generated by taking an element from the first array and // and an element from the second array. The function doesn't need to return any value. It // should just print to the terminal.

let printCombinations = function ( array1, array2 ) { for ( let i = 0; i < array1.length; i++ ) { let ele1 = array1[ i ];

for ( let j = 0; j < array2.length; j++ ) {
  let ele2 = array2[ j ];
  console.log( ele1, ele2 );
}

} };

let colors = [ "gray", "cream", "cyan" ]; let clothes = [ "shirt", "flannel" ]; printCombinations( colors, clothes ); // prints // gray shirt // gray flannel // cream shirt // cream flannel // cyan shirt // cyan flannel

printCombinations( [ "hot", "cold" ], [ "soup", "tea" ] ); // prints // hot soup // hot tea // cold soup // cold tea // Write a function named productUpTo(max) that accepts a max number as an argument. The function // should return the total product of all whole numbers from 1 to the max, inclusive. A product is a // number obtained from multiplying numbers together. // // For example, productUpTo(4) should return 24 because 1 * 2 * 3 * 4 = 24

let productUpTo = function ( max ) { let product = 1;

for ( let i = 1; i <= max; i++ ) { product *= i; }

return product; };

console.log( productUpTo( 4 ) ); // 24 console.log( productUpTo( 5 ) ); // 120 console.log( productUpTo( 7 ) ); // 5040 let word = "suspension bridge"; console.log( word[ 4 ] ); // e console.log( word.length > 5 && word[ 0 ] === "d" ); // false console.log( word.length > 5 && word[ 0 ] === "s" ); // true console.log( word.indexOf( "o" ) > -1 ); // true console.log( word.indexOf( "z" ) > -1 ); // false

let str = "foggy"; console.log( str[ 2 + 1 ] ); // g console.log( str[ str.length - 1 ] ); // y str = " day"; console.log( str ); // ' day' console.log( str.length ); // 4 console.log( str.indexOf( "ogg" ) ); // -1 // Write a function raisePower(base, exponent) that accepts two numbers, base and exponent. The // function should return base raised to the exponent power. // // For example, raisePower(2, 5) should return 32 because 2 * 2 * 2 * 2 * 2 = 32 // For example, raisePower(4, 3) should return 64 because 4 * 4 * 4 = 64

let raisePower = function ( base, exponent ) { let product = 1;

for ( let i = 1; i <= exponent; i++ ) { product *= base; }

return product; };

console.log( raisePower( 2, 5 ) ); // 32 console.log( raisePower( 4, 3 ) ); // 64 console.log( raisePower( 10, 4 ) ); // 10000 console.log( raisePower( 7, 2 ) ); // 49 // Write a function removeCapitals that accepts a string as an argument. The function should return a // new version of the string with all capital letters removed.

let removeCapitals = function ( str ) { let newStr = '';

for ( let i = 0; i < str.length; i++ ) { let char = str[ i ]; if ( char === char.toLowerCase() ) { newStr += char; } }

return newStr; };

console.log( removeCapitals( "fOrEver" ) ); // 'frver' console.log( removeCapitals( "raiNCoat" ) ); // 'raioat' console.log( removeCapitals( "cElLAr Door" ) ); // 'clr oor' // Write a function removeDupes that accepts an array as an argument. The function should return a // new array where each element only appears once.

let removeDupes = function ( array ) { let uniques = [];

for ( let i = 0; i < array.length; i++ ) { let ele = array[ i ]; if ( !uniques.includes( ele ) ) { uniques.push( ele ); } }

return uniques; };

console.log( removeDupes( [ "x", "y", "y", "x", "z" ] ) ); // ['x', 'y', 'z'] console.log( removeDupes( [ false, false, true, false ] ) ); // [false, true] console.log( removeDupes( [ 42, 5, 7, 42, 7, 3, 7, 7 ] ) ); // [42, 5, 7, 3] // Write a function removeFirstVowel that accepts a string as an argument. The function should return // the string with it's first vowel removed.

let removeFirstVowel = function ( str ) { let vowels = 'aeiou';

for ( let i = 0; i < str.length; i++ ) { let char = str[ i ]; if ( vowels.includes( char ) ) { return str.slice( 0, i ) + str.slice( i + 1 ); } }

return str; };

console.log( removeFirstVowel( "volcano" ) ); // 'vlcano' console.log( removeFirstVowel( "celery" ) ); // 'clery' console.log( removeFirstVowel( "juice" ) ); // 'jice' console.log( removeFirstVowel( "bridge" ) ); // 'brdge' console.log( removeFirstVowel( "try" ) ); // 'try' // Write a function removeShortWords that accepts a sentence string as an argument. The function // should return a new sentence where all of the words shorter than 4 characters are removed.

let removeShortWords = function ( sentence ) { let words = sentence.split( ' ' ); let chosenWords = [];

for ( let i = 0; i < words.length; i++ ) { let word = words[ i ];

if ( word.length >= 4 ) {
  chosenWords.push( word );
}

}

return chosenWords.join( ' ' ); };

console.log( removeShortWords( "knock on the door will you" ) ); // 'knock door will' console.log( removeShortWords( "a terrible plan" ) ); // 'terrible plan' console.log( removeShortWords( "run faster that way" ) ); // 'faster that' // Write a function removeVowels that accepts a string as an argument. The function should return // a version of the string where all vowels are removed.

let removeVowels = function ( str ) { let newStr = ''; let vowels = 'aeiou';

for ( let i = 0; i < str.length; i++ ) { let char = str[ i ]; if ( !vowels.includes( char ) ) { newStr += char; } }

return newStr; };

console.log( removeVowels( "jello" ) ); // jll console.log( removeVowels( "sensitivity" ) ); // snstvty console.log( removeVowels( "cellar door" ) ); // cllr dr // Write a function reverseArray that accepts an array as an argument. The function should return a // array containing the elements of the original array in reverse order.

let reverseArray1 = function ( array ) { let reversed = [];

for ( let i = array.length - 1; i >= 0; i-- ) { reversed.push( array[ i ] ); }

return reversed; };

console.log( reverseArray1( [ "zero", "one", "two", "three" ] ) ); // ['three', 'two', 'one', 'zero'] console.log( reverseArray1( [ 7, 1, 8 ] ) ); // [8, 1, 7]

let reverseArray2 = function ( array ) { let reversed = [];

for ( let i = 0; i < array.length; i++ ) { reversed.unshift( array[ i ] ); }

return reversed; };

console.log( reverseArray2( [ "zero", "one", "two", "three" ] ) ); // ['three', 'two', 'one', 'zero'] console.log( reverseArray2( [ 7, 1, 8 ] ) ); // [8, 1, 7] // Write a function reverseIterate that accepts a string as an argument. The function should print // the characters of the string one by one, in reverse order. The function doesn't need to return any // value. It should just print to the terminal.

let reverseIterate = function ( str ) { for ( let i = str.length - 1; i >= 0; i-- ) { console.log( str[ i ] ); } };

reverseIterate( "carrot" ); // prints // t // o // r // r // a // c

reverseIterate( "box" ); // prints // x // o // b // Write a function shortenLongWords that accepts a sentence string as an argument. The function // should return the same sentence where words longer than 4 characters have their vowels removed.

let removeVowels = function ( str ) { let newStr = ''; let vowels = 'aeiou';

for ( let i = 0; i < str.length; i++ ) { let char = str[ i ]; if ( !vowels.includes( char ) ) { newStr += char; } }

return newStr; };

let shortenLongWords = function ( sentence ) { let words = sentence.split( ' ' ); let newWords = [];

for ( let i = 0; i < words.length; i++ ) { let word = words[ i ]; if ( word.length > 4 ) { let noVowels = removeVowels( word ); newWords.push( noVowels ); } else { // leave it the same newWords.push( word ); } }

return newWords.join( ' ' ); };

console.log( shortenLongWords( "they are very noble people" ) ); // 'they are very nbl ppl' console.log( shortenLongWords( "stick with it" ) ); // 'stck with it' console.log( shortenLongWords( "ballerina, you must have seen her" ) ); // 'bllrna, you must have seen her console.log( "promenade" [ 3 ] ); // m console.log( "tiger" 1 ); // i console.log( "wheel".length ); // 5

console.log( "wheel".length - 1 ); // 4 console.log( "noMAD".toUpperCase() ); // NOMAD console.log( "hey programmers" [ 2 ] === "y" ); // true

console.log( "volleyball".length > 20 ); // false console.log( "treasure".indexOf( "r" ) ); // 1 console.log( "treasure".indexOf( "e" ) ); // 2 console.log( "web" [ 5 ] ); // undefined console.log( "red".indexOf( "x" ) ); // -1 console.log( "red".indexOf( "R" ) ); // -1 // snippet 0-1 let greet = function () { console.log( "hey" ); console.log( "programmers" ); };

let whistle = function () { console.log( "doot" ); };

console.log( "first" ); console.log( "second" ); greet(); console.log( "third" ); console.log( "fourth" ); whistle();

// first // second // hey // programmers // third // fourth // doot // snippet 0-2 let howMany = function () { return 42; };

console.log( howMany ); console.log( howMany() );

const theAnswer = howMany(); console.log( theAnswer );

let howMuch = function () { 5; }; console.log( howMuch() );

// [Function: howMany] // 42 // 42 // undefined // snippet 0-3 let average = function ( num1, num2 ) { console.log( "calculating..." ); return ( num1 + num2 ) / 2; };

console.log( average( 5, 10 ) ); console.log( average( 20, 26 ) ); console.log( average( 50, 100 ) + 2 );

let a = 21 + 3; let b = 20; let n = average( a, b ); console.log( average( n, 18 ) );

// calculating... // 7.5 // calculating... // 23 // calculating... // 77 // calculating... // calculating... // 20 // snippet 0-4 let exclaim = function ( str ) { let capitalized = str.toUpperCase(); return capitalized + "!!"; };

let result = exclaim( "potato" ); console.log( result ); console.log( result.length ); console.log( result[ 0 ] ); console.log( result[ result.length - 1 ] );

// POTATO!! // 8 // P // ! // snippet 1 console.log( "hello" );

for ( let i = 0; i < 5; i++ ) { console.log( "code" ); }

console.log( "goodbye" );

hello code code code code code goodbye // snippet 1 console.log( "hello" );

for ( let i = 0; i < 5; i++ ) { console.log( "code" ); }

console.log( "goodbye" );

hello code code code code code goodbye // snippet 2 console.log( "hi" );

for ( let i = 3; i <= 7; i++ ) { console.log( "program" ); console.log( i ); }

console.log( "bye" );

// hi // program // 3 // program // 4 // program // 5 // program // 6 // program // 7 // bye // snippet 2 console.log( "hi" );

for ( let i = 3; i <= 7; i++ ) { console.log( "program" ); console.log( i ); }

console.log( "bye" );

// hi // program // 3 // program // 4 // program // 5 // program // 6 // program // 7 // bye // snippet 3 let foo = function () { for ( let num = 10; num > 0; num -= 2 ) { console.log( num ); } };

console.log( "begin" ); foo(); console.log( "end" ); foo();

// begin // 10 // 8 // 6 // 4 // 2 // end // 10 // 8 // 6 // 4 // 2 // snippet 3 let foo = function () { for ( let num = 10; num > 0; num -= 2 ) { console.log( num ); } };

console.log( "begin" ); foo(); console.log( "end" ); foo();

// begin // 10 // 8 // 6 // 4 // 2 // end // 10 // 8 // 6 // 4 // 2 // snippet 4 let word = "street"; for ( let i = 0; i < word.length; i++ ) { console.log( i ); console.log( word[ i ] ); }

// 0 // s // 1 // t // 2 // r // 3 // e // 4 // e // 5 // t // snippet 4 let word = "street"; for ( let i = 0; i < word.length; i++ ) { console.log( i ); console.log( word[ i ] ); }

// 0 // s // 1 // t // 2 // r // 3 // e // 4 // e // 5 // t // snippet 5 let total = 0; // 10 for ( let i = 1; i < 5; i++ ) { total += i; console.log( total ); }

console.log( "grand total: " + total );

// 1 // 3 // 6 // 10 // grand total: 10 // snippet 5 let total = 0; // 10 for ( let i = 1; i < 5; i++ ) { total += i; console.log( total ); }

console.log( "grand total: " + total );

// 1 // 3 // 6 // 10 // grand total: 10 // Write a function spam that accepts a 2D array as an argument. The array contains pairs as elements. // The first element of every pair is a number and the second element is a word. The function should // return a string containing the words repeated the specified number of times. See the examples.

let spam = function ( pairs ) { let words = [];

for ( let i = 0; i < pairs.length; i++ ) { let pair = pairs[ i ]; let word = pair[ 0 ]; let num = pair 1 ;

for ( let j = 0; j < num; j++ ) {
  words.push( word );
}

}

return words.join( ' ' ); };

let array1 = [ [ "hi", 3 ], [ "bye", 2 ], ]; console.log( spam( array1 ) ); // 'hi hi hi bye bye'

let array2 = [ [ "cat", 1 ], [ "dog", 2 ], [ "bird", 4 ], ]; console.log( spam( array2 ) ); // 'cat dog dog bird bird bird bird' // Write a function startsWithR that accepts a string as an argument and returns a boolean indicating // whether or not the string starts with 'r' or 'R'.

let startsWithR = function ( str ) { return str[ 0 ] === 'r' || str[ 0 ] === 'R'; };

console.log( startsWithR( "roger that" ) ); // true console.log( startsWithR( "Row, row, row your boat" ) ); // true console.log( startsWithR( "slip" ) ); // false console.log( startsWithR( "Taxicab" ) ); // false // Write a function stayPositive that accepts an array of numbers as an argument. The function should // return an array containing only the positive numbers.

let stayPositive = function ( numbers ) { let positives = [];

for ( let i = 0; i < numbers.length; i++ ) { if ( numbers[ i ] > 0 ) { positives.push( numbers[ i ] ); } }

return positives; };

console.log( stayPositive( [ 10, -4, 3, 6 ] ) ); // [10, 3, 6] console.log( stayPositive( [ -5, 11, -40, 30.3, -2 ] ) ); // [11, 30.3] console.log( stayPositive( [ -11, -30 ] ) ); // [] console.log( "river" + "town" ); console.log( "cat" + "dog" ); console.log( "New" + " York" ); console.log( "runner's knee" + "!" ); console.log( "man" + "bear" + "pig" ); // Write a function stringIterate that accepts a string as an argument. The function should print out // each character of the string, one by one. The function doesn't need to return any value. It should // just print to the terminal.

let stringIterate = function ( string ) { for ( let i = 0; i < string.length; i++ ) { console.log( string[ i ] ); } };

stringIterate( "celery" ); // prints // c // e // l // e // r // y

stringIterate( "hat" ); // prints // h // a // t // Write a function named stringRepeater(str, num) that accepts a string and a number as arguments. // The function should return a new string consisting of the str repeated num number of times.

let stringRepeater = function ( str, num ) { let repeatedStr = '';

for ( let i = 1; i <= num; i++ ) { repeatedStr += str }

return repeatedStr; };

console.log( stringRepeater( "q", 4 ) ); // 'qqqq' console.log( stringRepeater( "go", 2 ) ); // 'gogo' console.log( stringRepeater( "tac", 3 ) ); // 'tactactac' // Write a function stringSize that accepts a string as an argument. The function should return the // string 'small' if the argument is shorter than 5 characters, 'medium' if it is exactly 5 characters, and // 'large' if it is longer than 5 characters.

let stringSize = function ( str ) { if ( str.length < 5 ) { return 'small'; } else if ( str.length > 5 ) { return 'large'; } else { return 'medium'; } };

console.log( stringSize( "cat" ) ); // 'small' console.log( stringSize( "bell" ) ); // 'small' console.log( stringSize( "ready" ) ); // 'medium' console.log( stringSize( "shirt" ) ); // 'medium' console.log( stringSize( "shallow" ) ); // 'large' console.log( stringSize( "intelligence" ) ); // 'large' // Write a function stringsToLengths that accepts an array of strings as an argument. The function // should return a new array containing the lengths of the elements of the original array.

let stringsToLengths = function ( words ) { let lengths = [];

for ( let i = 0; i < words.length; i++ ) { lengths.push( words[ i ].length ); }

return lengths; };

console.log( stringsToLengths( [ "belly", "echo", "irony", "pickled" ] ) ); // [5, 4, 5, 7]

console.log( stringsToLengths( [ "on", "off", "handmade" ] ) ); // [2, 3, 8] // Write a function named sumUpTo(max) that accepts a max number as an argument. The function should // return the total sum of all whole numbers from 1 to the max, inclusive. // // For example, sumUpTo(4) should return 10 because 1 + 2 + 3 + 4 = 10.

let sumUpTo = function ( max ) { let sum = 0;

for ( let i = 1; i <= max; i++ ) { sum += i }

return sum; };

console.log( sumUpTo( 4 ) ); // 10 console.log( sumUpTo( 5 ) ); // 15 console.log( sumUpTo( 2 ) ); // 3 console.log( 'coffee' ); let qty = 15 % 4; console.log( qty ); // 3

let num = 38 + 3; num++; console.log( num + " is a great number" ); // '42 is a great number'

let isNumEven = num % 2 === 0; console.log( num + " is even? " + isNumEven ); // '42 is even? true'

let isQtyEven = qty % 2 === 0; console.log( qty + " is even? " + isQtyEven ); // '3 is even? false' let qty = 15 % 4; console.log( qty ); // 3

let num = 38 + 3; num++; console.log( num + " is a great number" ); // '42 is a great number'

let isNumEven = num % 2 === 0; console.log( num + " is even? " + isNumEven ); // '42 is even? true'

let isQtyEven = qty % 2 === 0; console.log( qty + " is even? " + isQtyEven ); // '3 is even? false' // Write a function totalProduct(array) that accepts a 2D array of numbers. The function should return // the total product of all numbers in the array.

let totalProduct = function ( array ) { let product = 1;

for ( let i = 0; i < array.length; i++ ) { let subarray = array[ i ];

for ( let j = 0; j < subarray.length; j++ ) {
  product *= subarray[ j ];
}

}

return product; };

let array1 = [ [ 3, 5, 2 ], [ 6, 2 ], ]; console.log( totalProduct( array1 ) ); // 360

let array2 = [ [ 4, 6 ], [ 2, 3 ], [ 1, 2 ], ]; console.log( totalProduct( array2 ) ); // 288 // Write a function total that accepts an array of numbers as an argument. The function should return // the total sum of all elements of the array.

let total = function ( numbers ) { let sum = 0; for ( let i = 0; i < numbers.length; i++ ) { sum += numbers[ i ]; } return sum; };

console.log( total( [ 3, 2, 8 ] ) ); // 13 console.log( total( [ -5, 7, 4, 6 ] ) ); // 12 console.log( total( [ 7 ] ) ); // 7 console.log( total( [] ) ); // 0 let apple; console.log( apple ); // undefined

apple = 5; console.log( apple ); // 5

apple + 1; console.log( apple ); // 5

apple += 1; console.log( apple ); // 6

let banana = apple; console.log( banana ); // 6

banana = banana / 2; console.log( banana ); // 3

console.log( apple ); // 6 // Write a function twoSumPairs(numbers, target) that accepts an array of numbers and a target number // as arguments. The function should return a 2D array containing all unique pairs of elements that // sum to the target.

let twoSumPairs = function ( numbers, target ) { let pairs = [];

for ( let i = 0; i < numbers.length; i++ ) { let num1 = numbers[ i ];

for ( let j = i + 1; j < numbers.length; j++ ) {
  let num2 = numbers[ j ];

  if ( num1 + num2 === target ) {
    let pair = [ num1, num2 ];
    pairs.push( pair );
  }
}

}

return pairs; };

console.log( twoSumPairs( [ 2, 3, 4, 6, 5 ], 8 ) ); // [ [2, 6], [3, 5] ] console.log( twoSumPairs( [ 10, 7, 4, 5, 2 ], 12 ) ); // [ [10, 2], [7, 5] ] console.log( twoSumPairs( [ 3, 9, 8 ], 11 ) ); // [ [3, 8] ] console.log( twoSumPairs( [ 3, 9, 8 ], 10 ) ); // [ ] // Write a function twoSum(numbers, target) that accepts an array of numbers and a target number // as an argument. The function should return a boolean indicating whether or not there exists a pair // of distinct elements in the array that sum to the target.

let twoSum = function ( numbers, target ) { for ( let i = 0; i < numbers.length; i++ ) { for ( let j = i + 1; j < numbers.length; j++ ) { if ( numbers[ i ] + numbers[ j ] === target ) { return true; } } }

return false; };

console.log( twoSum( [ 2, 3, 5, 9 ], 7 ) ); // true console.log( twoSum( [ 2, 3, 5, 9 ], 4 ) ); // false console.log( twoSum( [ 6, 3, 4 ], 10 ) ); // true console.log( twoSum( [ 6, 5, 1 ], 10 ) ); // false let apple; console.log( apple ); // undefined

apple = 5; console.log( apple ); // 5

apple + 1; console.log( apple ); // 5

apple += 1; console.log( apple ); // 6

let banana = apple; console.log( banana ); // 6

banana = banana / 2; console.log( banana ); // 3

console.log( apple ); // 6 // Write a function wackyWord that accepts two strings as arguments. The function should return a new // string containing the first three characters of the first string concatenated with the last two // character of the second string.

// You can assume that the first argument has a length of at least three and the second argument has a // length of at least two.

let wackyWord = function ( str1, str2 ) { return str1.slice( 0, 3 ) + str2.slice( -2 ); };

console.log( wackyWord( "very", "kindly" ) ); // 'verly' console.log( wackyWord( "forever", "sick" ) ); // 'forck' console.log( wackyWord( "cellar", "door" ) ); // 'celor' console.log( wackyWord( "bagel", "sweep" ) ); // 'bagep' console.log( 'alvin' ); console.log( 'z' ); // Write a function wordCount(sentence, targetWords) that accepts a sentence string and an array of // targetWords. The function should return a count of the number of words of the sentence that are // in targetWords.

let wordCount = function ( sentence, targetWords ) { let words = sentence.split( ' ' ); let count = 0;

for ( let i = 0; i < words.length; i++ ) { let word = words[ i ];

if ( targetWords.includes( word ) ) {
  count++;
}

}

return count; };

console.log( wordCount( "open the window please", [ "please", "open", "sorry" ] ) ); // 2 console.log( wordCount( "drive to the cinema", [ "the", "driver" ] ) ); // 1 console.log( wordCount( "can I have that can", [ "can", "I" ] ) ); // 3 // Write a function yourAverageFunction that accepts an array of numbers as an argument. The // function should return the average of all elements of the array. If the input array is empty, // then the function should return null.

let yourAverageFunction = function ( nums ) { if ( nums.length === 0 ) { return null; }

let sum = 0; for ( let i = 0; i < nums.length; i++ ) { sum += nums[ i ]; }

return sum / nums.length; };

console.log( yourAverageFunction( [ 5, 2, 7, 24 ] ) ); // 9.5 console.log( yourAverageFunction( [ 100, 6 ] ) ); // 53 console.log( yourAverageFunction( [ 31, 32, 40, 12, 33 ] ) ); // 29.6 console.log( yourAverageFunction( [] ) ); // null let location = "Brooklyn, " + "NY"; console.log( location ); // 'Brooklyn, NY'

let quantity = 4 * 5 + 1; console.log( quantity ); // 21 let location = "Brooklyn, " + "NY"; console.log( location ); // 'Brooklyn, NY'

let quantity = 4 * 5 + 1; console.log( quantity ); // 21 // Write a function zipper that accepts two arrays as arguments. The function should return a 2D // array containing pairs of elements at the same indices.

let zipper = function ( arr1, arr2 ) { let result = [];

for ( let i = 0; i < arr1.length; i++ ) { let el1 = arr1[ i ]; let el2 = arr2[ i ]; let pair = [ el1, el2 ]; result.push( pair ); }

return result; };

let array1 = [ "a", "b", "c", "d" ]; let array2 = [ -1, -2, -3, -4 ]; console.log( zipper( array1, array2 ) ); // [ // ['a', -1], // ['b', -2], // ['c', -3], // ['d', -4], // ]

let array3 = [ "whisper", "talk", "shout" ]; let array4 = [ "quiet", "normal", "loud" ]; console.log( zipper( array3, array4 ) ); // [ // ['whisper', 'quiet'], // ['talk', 'normal'], // ['shout', 'loud'], // ]

javascript-practice/00_expressions_variables/exercises/A_executing_code_exercise/

Write, Run, Repeat

You won't become a strong programmer with "one secret trick" or "however-many expert tips". No shortcuts. Just write code, run it, do it again. We'll be creating and executing hundreds of programs in this course. Let's bang out the first four.

Before you start this exercise, make sure you have watched the lecture first.

If you get stuck during this exercise, reference this walkthrough. Only watch enough of the walkthrough to get yourself unstuck, then pause the video and pick up the exercise on your own.

Let's get to work.

-AZ

0. Follow my lead.

  1. If you already have VSCode open, close it.
  2. On your computer's Desktop, create a new folder named my-first-programs.
  3. Open the my-first-programs folder in VSCode
  4. Use VSCode to create a file named greeting.js inside of my-first-programs.
  5. Inside of greeting.js, write the single line of code console.log('hello world');. This will cause the program to print hello world when you execute it later.
  6. Save the greeting.js file using the keyboard shortcut cmd + s or ctrl + s.
  7. Open the terminal and enter the command node greeting.js to execute your code. You should see hello world printed out.

1. Still following?

  1. Inside the my-first-programs folder, create a new file named whoami.js.
  2. Inside of whoami.js use console.log to print out your first name. Don't forget to put quotation marks (') around your name and end the line with a semicolon (;).
  3. Save whoami.js and execute it in your terminal using the node. You should see your name printed out.

2. I'll follow you.

Start from scratch. Close VSCode if you have it open. Use VSCode to write a program named thirsty.js inside of the my-first-programs folder. The program should print out your favorite cold beverage. Execute thirsty.js in your terminal.

3. Beginner's luck; show me it again.

That seems suspicious. Write a program named age.js that prints out your age. Run it.

Walkthrough

javascript-practice/00_expressions_variables/exercises/B_expressions_exercise/

Express Yourself

Expressions are the building blocks of programs. We can combine values with operators to compose an expression. An expression evaluates to some value.

Before you start this exercise, make sure you have watched the lecture first.

If you get stuck during this exercise, reference this walkthrough. Only watch enough of the walkthrough to get yourself unstuck, then pause the video and pick up the exercise on your own.

The fundamentals of any skill aren't particularly glamorous. We'll learn the "cool" stuff when you are ready. Crawl. Walk. Run.

-AZ

0. Hope you didn't forget.

Create a new folder named expressions-exercise. Open it in VSCode. Create four files within this folder: string-expressions.js, number-expressions.js, boolean-expressions.js, comparisons.js.

After creating these files, your folder structure should look like this:

expressions-exercise/
├── string-expressions.js
├── number-expressions.js
├── boolean-expressions.js
└── comparisons.js

1. Stringing together some expressions.

Make a mental prediction of what the following expressions will print:

console.log("river" + "town");
console.log("cat" + "dog");
console.log("New" + " York");
console.log("runner's knee" + "!");
console.log("man" + "bear" + "pig");

To check your prediction, write the code into string-expressions.js and run it in your terminal with node string-expressions.js. Don't copy and paste. Type everything manually. You should do this line by line. This means you should type the first expression, run it. Add the second expression, run it, and so on. Don't try to type all five lines and then run it all at once. You will find it hard to pinpoint any typos if you do that.

2. Don't enjoy math? Too bad.

Make predictions for what these number expressions evaluate to. Test your predictions by writing the code to number-expressions.js and running it:

console.log(2 + 3);
console.log(10 - 15);
console.log(4 + 1 - 5);
console.log(4 * 3);

console.log(7 / 2);
console.log(4 + 2 * 3);
console.log((4 + 2) * 3);
console.log(5 % 2);

console.log(6 % 2);
console.log(7 % 2);
console.log(8 % 2);
console.log(19 % 8);

console.log(24 % 8);
console.log(7 % 4);
console.log(4 % 7);
console.log(5 + (10 % 5));
console.log((5 + 10) % 5);

3. Shoutout to George Boole.

Make predictions for what these boolean expressions evaluate to. Test your predictions by writing the code to boolean-expressions.js and running it:

console.log(false);
console.log(!true);
console.log(!false);
console.log(!!true);

console.log(false && false);
console.log(false && true);
console.log(true && false);
console.log(true && true);

console.log(false || false);
console.log(false || true);
console.log(true || false);
console.log(true || true);

console.log(!false || false);
console.log(false || (true && true));
console.log(false || !(true && true));
console.log(!true && (false || true));

4. Drawing a Comparison.

Make predictions for what these comparison expressions evaluate to. Test your predictions by writing the code to comparisons.js and running it:

console.log(true === false);
console.log(false === false);
console.log(false !== true);
console.log(!true === false);

console.log(2 + 3 === 5);
console.log(4 < 0);
console.log(10 >= 10);
console.log(10.3 >= 10);

console.log(100 / 2 === 50);
console.log(100 % 2 === 0);
console.log(11 % 2 === 0);
console.log(7.0 === 7);

console.log(13 % 5 > 0);
console.log("potato" === "potato");
console.log("Tomato" === "tomato");
console.log("42" === 42);
console.log(5 > 3 && 1 === 0);

Walkthrough

javascript-practice/00_expressions_variables/exercises/C_variables_exercise/

Very Able

Variables allow programmers to store values to be used later in their code. The value that a variable contains can change throughout the runtime of a program.

Before you start this exercise, make sure you have watched the lecture first.

If you get stuck during this exercise, reference this walkthrough. Only watch enough of the walkthrough to get yourself unstuck, then pause the video and pick up the exercise on your own.

Ready?

-AZ

0. Do you speak the language?

Create a folder named variables_exercise. Create a file named zero.js inside of it. Predict what the console.logs in the code below will print out:

let location = "Brooklyn, " + "NY";
console.log(location);

let quantity = 4 * 5 + 1;
console.log(quantity);

Test your predictions by typing the code into the zero.js file; don't copy and paste. Run it to check your guess.

1. What's changed? What hasn't?

Create a new file named one.js inside of the variables_exercise folder. Predict what the console.logs in the code below will print out:

let word = "bye";
console.log(word + " felicia");
console.log(word);

let num = 10;
num = num * 2;
console.log(num);

let bottlesOfBeer = 99;
let around = bottlesOfBeer - 1;
console.log(around);
console.log(bottlesOfBeer);

Test your predictions by typing the code into the one.js file. Run it.

2. How about this?

Create a new file named two.js inside of the variables_exercise folder. Predict what the console.logs in the code below will print out:

let apple;
console.log(apple);

apple = 5;
console.log(apple);

apple + 1;
console.log(apple);

apple

Releases

No releases published

Packages

No packages published

Languages

  • HTML 71.2%
  • JavaScript 28.8%