0.) Links:
HTML TAG EXAMPLES Navigation Playground Quiz Me Text-Tools Github HTML FilePreviewersimple-sidebar-template My Blog Posts
.
├── 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
Expression Learning Objectives Intro to Functions Learning Objectives
- Hello World
- The Number Type
- The String Type
- The Boolean Type
- Comparison Operators
- Basic Variables
- Introduction to Functions
- Parameters and Arguments
Control Flow and Array Learning Objectives
- Control Flow - Conditional Statements
- Mutually Exclusive Conditions
- Control Flow - Looping
- The Array Type
Intermediate Functions Learning Objectives
- Function Expressions
- Two-Dimensional Arrays (2D Arrays)
- Mutability in JavaScript
- Array Splice
- String#split and Array#join
- Determining Types
- The Null Type (And Undefined)
- Catch Me If You Can
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.
-
Given a working REPL interface, write and execute a statement that will print "hello world" using console.log
-
Identify that strings are a list of characters defined by using double or single quotes
-
Given an arithmetic expression using +, -, *, /, %, compute its value
-
Given an expression, predict if its value is NaN
-
Construct the truth tables for &&, ||, !
-
Given an expression consisting of >, >=, ===, <, <=, compute it's value
-
Apply De Morgan's law to a boolean expression
-
Given an expression that utilizes operator precedence, compute its value
-
Given an expression, use the grouping operator to change it's evaluation
-
Given expressions using == and ===, compute their values
-
Given a code snippet using postfix ++, postfix --, +=, -=, /=, *=, predict the value of labeled lines
-
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. -
Given a working REPL interface, write and execute a statement that will print "hello world" using console.log
-
Identify that strings are a list of characters defined by using double or single quotes
-
Given an arithmetic expression using +, -, *, /, %, compute its value
-
Given an expression, predict if its value is NaN
-
Construct the truth tables for &&, ||, !
-
Given an expression consisting of >, >=, ===, <, <=, compute it's value
-
Apply De Morgan's law to a boolean expression
-
Given an expression that utilizes operator precedence, compute its value
-
Given an expression, use the grouping operator to change it's evaluation
-
Given expressions using == and ===, compute their values
-
Given a code snippet using postfix ++, postfix --, +=, -=, /=, *=, predict the value of labeled lines
-
Create and assign a variable using
let
to a string, integer, and a boolean. Read its value and print to the console.
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.
-
Define a function using function declaration
-
Define a function that calculates the average of two numbers, call it, pass in arguments, and print it's return value
-
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.
-
Define a function using function declaration
-
Define a function that calculates the average of two numbers, call it, pass in arguments, and print it's return value
-
Identify the difference between parameters vs arguments
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
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.
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!
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
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 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
JavaScript's Number encompasses numerical values. All of the following values are of number type:
42;
-5;
3.14159;
7.0;
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
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
- 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 dividea
byb
; we call this operation modulo- JavaScript follows the usual mathematical order of operations and we can use
the
()
to force precedence
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
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.
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
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.
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.
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 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'
- a String is a data type that contains multiple characters enclosed in quotation marks
string.length
returns the number of characters in thestring
- 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 ofchar
withinstring
; ifchar
is not found, then -1 is returned - we can use
+
to concatenate multiple strings, combining them into a single string
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
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)
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.
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
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
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.
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.
!
,&&
,||
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!
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===
>
(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.
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.
>
,<
,>=
,<=
,===
, and!==
can be used to compare values- we prefer to use
===
to check for equality because it takes the type into account.
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
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.
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.
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); // ''
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.
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
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
- variables are declared with
let
and will contain the valueundefined
by default - we can use single-equals
=
to assign variables - changing a variable requires a reassignment, for which there are many
shortcuts for (
+=
,-=
, etc.)
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:
- Describe what a function in JavaScript is.
- Demonstrate how to invoke a function.
- Write a function using function declaration.
- Use the
return
keyword to return a value from a function.
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.
A function definition consists of the function keyword, followed by three things:
- The name of the function.
- A list of parameters to the function, enclosed in parentheses,
()
. - 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.
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.
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:
- 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. - JS prints out
First!
- JS sees that we are calling
callMe()
. At this point it will look at the priorcallMe
definition and run the code inside. It is as if we are "jumping" to inside the function definition. This means it will printSecond!
followed byThird!
- JS sees there is no more code to be run inside of
callMe
, so it "jumps" back to where we originally calledcallMe()
- JS will continue evaluating in order and print
Fourth!
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.
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:
- We declared the
sayNumber
function sayNumber
was called handing in the argument of 1- The
number
parameter is printed to the console - 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 isundefined
.
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:
- Every function call evaluates to it's return value.
- Every function in JavaScript returns
undefined
unless areturn
is specified - Once a
return
statement is encountered the function will immediately stop and return the value, ignoring any code below thereturn
statement.
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.
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
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:
- Identify the difference between parameters and arguments.
- Write a function that utilizes declared parameters.
- Invoking a function with passed in arguments.
Let's start off by talking about the difference between arguments and parameters and how to identify which is which.
- Parameters are comma separated variables specified as part of a function's declaration.
- 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!
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.
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:
firstParameter
was set to equal the first passed in argument which in the above case is 5.- Since there is no second argument then
secondParameter
is declared as a variable but is set to the default value ofundefined
. - The function then tries to add 5 to
undefined
which is definitely not a number! So we getNaN
(which meansNot 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.
- 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.
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.
-
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.
-
Identify a pair of mutually exclusive conditions
-
Given a for loop, translate it into a while loop, and vice-versa
-
Write a function that iterates through a provided string argument
-
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.
-
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.
-
Define that an array literal is an ordered list of values defined by using bracket and individual values are read by indexing.
-
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.
-
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.
-
Identify a pair of mutually exclusive conditions
-
Given a for loop, translate it into a while loop, and vice-versa
-
Write a function that iterates through a provided string argument
-
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.
-
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.
-
Define that an array literal is an ordered list of values defined by using bracket and individual values are read by indexing.
-
Prevent code that can throw an exception from causing the program to crash.
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 oneelse
statement. - Identify that conditional statements can be nested.
Before we get started we'll quickly go over the terms we'll be using to represent syntax.
[ ]
are square brackets{ }
are curly braces( )
are parentheses
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"
- 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 oneelse
statement. - Conditional statements can be nested.
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.
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!
- How to identify a pair of mutually exclusive conditions.
- DRY - don't repeat yourself!
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:
- Know how to write a
while
loop and afor
loop.- Know how to convert a
for
loop into awhile
loop
- Know how to convert a
- Know that index variables conventionally start at zero.
- Explain what an iteration is.
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.
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.
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.
A for
loop can be broken down into three sections:
- The initial expression which will be run once at the beginning of the loop.
- 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.
- 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.
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]
- We can use a
for
orwhile
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.
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
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"
];
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
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!
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
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).
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!
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]
- 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 thearray
.- 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 ofvalue
withinarray
; ifvalue
is not found, then -1 is returned. - We can use
.concat
to concatenate multiple arrays, combining them into a single array.
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.
-
Identify that strings are immutable and arrays are mutable
-
Define a function using both function declaration and function expression syntax
-
Utilize Array#push, #pop, #shift, #unshift to mutate an array
-
List the arguments that can be used with Array#splice
-
Write a function that sums up elements of an array, given an array of numbers as an argument
-
Utilize Array#forEach, #map, #filter, #reduce in a function
-
Define a function that takes in an array of numbers and returns a new array containing only the primes
-
Define a function that takes in a 2D array of numbers and returns the total sum of all elements in the array
-
Define a function that takes in an array of elements and returns a 2d array where the subarrays represent unique pairs of elements
-
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.
-
Identify that strings are immutable and arrays are mutable
-
Define a function using both function declaration and function expression syntax
-
Utilize Array#push, #pop, #shift, #unshift to mutate an array
-
List the arguments that can be used with Array#splice
-
Write a function that sums up elements of an array, given an array of numbers as an argument
-
Utilize Array#forEach, #map, #filter, #reduce in a function
-
Define a function that takes in an array of numbers and returns a new array containing only the primes
-
Define a function that takes in a 2D array of numbers and returns the total sum of all elements in the array
-
Define a function that takes in an array of elements and returns a 2d array where the subarrays represent unique pairs of elements
-
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
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
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!
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 tomyFunc
as ananonymous function
because an anonymous function has no name.
- functions can be stored in variables; just like any other values in JavaScript!
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
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'
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
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)
- an array can contain arrays as elements, we call this a 2D arrays
- to iterate through a 2D array, used nested loops
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
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.
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.
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.
- 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
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
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
.
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.
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.
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'
."
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:
- 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
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
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!
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.
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.
- we can use
String#split
andArray#join
to convert between strings and arrays - both methods do not mutate their input
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
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. :-(');
}
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
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 ...
}
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!
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.
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
.
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.
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
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(' ');
}
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.
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');
}
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
}
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() {
}
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
.
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?
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.
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.
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');
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;
}
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;
}
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 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.
Below are some of the most common ways to include jQuery.
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
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";
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 is a module format built for the browser. For more information, we recommend require.js' documentation.
define( [ "jquery" ], function( $ ) {
} );
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/
- fixed
object/get
throwing an exception for null or undefined input objects
- update dependencies
- optimize
function/bind
- optimize
lang/kindOf
- add
array/indicesOf
- add
function/memoize
- add
array/reverse
- add
math/overflow
- fix
query/getQuery
- fix
object/deepMatches
- optimize
function/partial
- updates license
- add
array/take
; - remove unused variable from
date/totalDaysInMonth
; - fix case insensitive RegExp cloning on
lang/clone
;
- 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 returntrue
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 whereval === min === max
; - improve
object/get
behavior to return properties from any value that is notnull
orundefined
; - move
object/deepEquals
tolang/deepEquals
(improving the behavior);
- fix
array/slice
behavior when start and end are higher than length.
- add
date/quarter
; - add
function/constant
; - add
random/randBool
; - add un-padded 12-hour (
%l
) todate/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 theprototype
; - improve
string/removeNonWord
to cover more chars; - improve
string/repeat
performance; - improve
string/unescapeHtml
by accepting leading zeros for'
;
- 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 (usesidentity
by default). - simplify
string/escapeRegExp
. - support custom equality on
array/compare
.
- fix
null
value handling in object/get.
- add bower ignores.
- add german translation for date localization.
- alias
function
package asfn
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 tothrottled/debounced
functions. - add
function/times
. - add
lang/toNumber
. - add
string/insert
. - add
super_
to constructor onlang/inheritPrototype
.
- add optional delimeter to
string/unCamelCase
- allow custom char on
number/pad
- allow underscore characters in
string/removeNonWord
- accept
level
onarray/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
- add
array/collect
- add
callback
parameter toobject/equals
andobject/deepEquals
to allow custom compare operations. - normalize behavior in
array/*
methods to treatnull
values as empty arrays when reading from array - add
date/parseIso
- add
date/isLeapYear
- add
date/totalDaysInMonth
- add
object/deepMatches
- change
function/makeIterator_
to usedeepMatches
(affects nearly all iteration methods) - add
thisObj
parameter toarray/min
andarray/max
- add
object/equals
- add
object/deepEquals
- add
object/matches
. - add
lang/is
andlang/isnt
. - add
lang/isInteger
. - add
array/findIndex
. - add shorthand syntax to
array/*
,object/*
andcollection/*
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).
- add
lang/clone
. - add
lang/toString
. - add
string/replace
. - add
string/WHITE_SPACES
- rename
function/curry
tofunction/partial
. - allow custom chars in
string/trim
,ltrim
, andrtrim
. - convert values to strings in the
string/*
functions.
- fix bug in
math/ceil
for negative radixes. - change
object/deepFillIn
andobject/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
tolang/deepClone
. - add VERSION property to index.js
- simplify
math/floor
,math/round
,math/ceil
andmath/countSteps
.
- Rename project from "amd-utils" to "mout"
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 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).
The build script can be extremely helpful and can avoid human mistakes, use it.
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, ...).
If you are proposing some major change, please create an issue to discuss it first. (maybe it's outside the scope of the project)
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 utilities.
Appends an array to the end of the other. The first array will be modified and will contain the appended items.
var foo = ['a', 'b'],
bar = ['b', 'd'];
append(foo, bar); // ['a', 'b', 'b', 'd']
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];
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.
var foo = ['a', 'b'],
bar = ['b', 'd'];
combine(foo, bar); // ['a', 'b', 'd']
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'];
Checks if Array contains value. Alias to indexOf(arr, val) !== -1
.
var arr = [1, 2, 3];
contains(arr, 2); // true
contains(arr, 'foo'); // false
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']
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
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
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()
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()
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()
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()
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()
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.
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()
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
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']}
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
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]
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]
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]
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]]
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.
join(['a', 'b', 'c']); // 'abc'
join(['foo', 'bar'], ', '); // 'foo, bar'
join([null, 'foo', '', 'bar', undefined], ':'); // 'foo:bar'
Returns the last element of an array without modifying the array.
last( [1, 2, 3, 4] ) // > 4
last( ['foo', 'bar'] ) // > 'bar'
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
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]
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"
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"
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()
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]
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]
Creates a new Array with all the values inside the range. Works similarly to Python#range or PHP#range.
[start]
(Number) : Range start. Default is0
.stop
(Number) : Range limit.[step]
(Number) : Step size. Default is1
.
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]
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
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
Creates a new array with all the elements that do not pass the truth test.
Opposite of filter()
.
See filter()
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 a single item from the array.
IMPORTANT: it won't remove duplicates, just a single item.
var foo = [1, 2, 3, 4];
remove(foo, 2);
console.log(foo); // [1, 3, 4]
Remove all instances of an item from the array.
var foo = [1, 2, 3, 4, 2, 2];
removeAll(foo, 2);
console.log(foo); // [1, 3, 4];
Returns a copy of the array with all elements in reversed order.
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];
Returns a new Array with items randomly sorted (shuffled). Similar to Ruby Array#shuffle.
var arr = ['a', 'b', 'c', 'd', 'e'];
shuffle(arr); // ['b', 'd', 'e', 'c', 'a']
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.
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]
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
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
.
If compareFn
is supplied elements are sorted based on the value returned by
the compareFn
.
- If
compareFn(a, b)
is less than0
, sorta
to a lower index thanb
. - If
compareFn(a, b)
returns0
, leavea
andb
unchanged with respect to each other, but sorted with respect to all different elements. - If
compareFn(a, b)
is greater than0
, sortb
to a lower index thana
.
See: sortBy
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;
});
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');
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.
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] ]
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
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.
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; });
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']
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'}]
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']
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...
Methods for dealing with collections (Array or Objects).
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
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 collection properties.
See: array/filter, object/filter
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
Loop through all values of the collection.
See: array/forEach, object/forOwn
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
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'
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'
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
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
Creates a new array with all the elements that do not pass the truth test.
Opposite of filter()
.
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
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
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 utilities.
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
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
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
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
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
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
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
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.
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"
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
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
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
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*(al)* utilities.
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);
});
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);
fn
(Function) : Target Functiondelay
(Number) : Delay of execution in milliseconds
See: debounce()
Return a function that will execute in the given context, optionally adding any additional supplied parameters to the beginning of the arguments collection.
fn
(Function) : Target Functioncontext
(Object) : Execution context (object used asthis
)[...args]
(*) : Arguments (0...n arguments)
See: partial()
, object/bindAll
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) );
});
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' }
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()
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'));
Returns the first argument provided to it.
identity(3); // 3
identity(1,2,3); // 1
identity('foo'); // "foo"
Return a partially applied function supplying default arguments.
This method is similar to bind
, except it does not alter the this
binding.
fn
(Function) : Target Function[...args]
(*) : Arguments (0...n arguments)
See: bind()
function add(a, b){ return a + b }
var add10 = partial(add, 10);
console.log( add10(2) ); // 12
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'));
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));
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()
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);
Iterates over a callback n
times.
n
(Number) : Number of iterationscallback
(Function) : Closure executed for every iterationcontext
(Object) : Execution context (object used asthis
)
var output = '';
times(5, function(i) {
output += i.toString();
});
// output: 01234
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'
See: partial()
For more usage examples check specs inside /tests
folder. Unit tests are the
best documentation you can get...
Language Utilities. Easier inheritance, scope handling, type checks.
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.
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()
Create Object using prototypal inheritance and setting custom properties.
Mix between Douglas Crockford Prototypal Inheritance and object/mixIn
.
parent
(Object) : Parent Object[props]
(Object) : Object properties
var base = {
trace : function(){
console.log(this.name);
}
};
var myObject = createObject(base, {
name : 'Lorem Ipsum'
});
myObject.trace(); // "Lorem Ipsum"
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"
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.
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()
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
Return first value that isn't null
or undefined
.
function doSomethingAwesome(foo, bar) {
// default arguments
foo = defaults(foo, 'lorem');
bar = defaults(bar, 123);
// ...
}
Reference to the global context (window
inside a browser, global
on
node.js). Works on ES3 and ES5 strict-mode.
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
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()
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()
If value is an "Arguments" object.
If value is an Array. Uses native ES5 Array.isArray()
if available.
If value is a Boolean.
If value is a Date.
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
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
If value is a Function.
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()
Check if value is an integer.
isInteger(123); // true
isInteger(123.45); // false
isInteger({}); // false
isInteger('foo'); // false
isInteger('123'); // false
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
If value is null
.
If value is a Number.
If value is an Object.
If the value is an Object created by the Object constructor.
If value is a RegExp.
If value is a String.
If value is undefined
.
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()
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()
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
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 utilities.
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
Round values by increments of 5/10/1000/etc.
See: round()
, floor()
, countSteps()
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
.
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()
Count number of full steps.
val
(Number) : Value.step
(Number) : Step size.[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
var containerWidth = 100;
var itemWidth = 8;
var howManyFit = countSteps(containerWidth, itemWidth); // 12
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);
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
Round values by increments of 5/10/1000/etc.
See: round()
, ceil()
, countSteps()
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
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...
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
Games where a certain action should happen if an actor is close to a target, gravity fields, any numeric check that has some tolerance.
Linear interpolation.
lerp(0.5, 0, 10); // 5
lerp(0.75, 0, 10); // 7.5
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.
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.
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()
Maps a number from one scale to another.
map(3, 0, 4, -1, 1) // 0.5
map(3, 0, 10, 0, 100) // 30
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
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
Convert values between scales, used by map()
internally. Direct
opposite of lerp()
.
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 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
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 utilities.
Abbreviate number to thousands (K), millions (M) or billions (B).
The default value for nDecimalDigits
is 1
.
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"
Format a number as currency.
currencyFormat(1000); // "1,000.00"
currencyFormat(1000, 1); // "1,000.0"
currencyFormat(1000, 2, ',', '.'); // "1.000,00"
Enforce a specific amount of decimal digits and also fix floating point rounding issues.
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
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
Maximum 32-bit signed integer value. Math.pow(2, 31) - 1
console.log( MAX_INT ); // 2147483647
Maximum safe integer. Math.pow(2,53) − 1
Maximum 32-bit unsigned integer value. Math.pow(2, 32) - 1
console.log( MAX_UINT ); // 4294967295
Minimum 32-bit signed integer value. Math.pow(2, 31) * -1
.
console.log( MIN_INT ); // -2147483648
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()
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()
Add padding zeros if n.length
< minLength
.
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
Bitwise circular shift left.
More info at Wikipedia#Circular_shift
Bitwise circular shift right.
More info at Wikipedia#Circular_shift
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
"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.
toInt(1.25); // 1
toInt(0.75); // 0
toInt(-0.55); // 0
toInt(-5.0001) // -5
"Convert" value into an 32-bit unsigned integer.
Works like AS3#uint().
IMPORTANT: val will wrap at 2^32.
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
"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
.
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 utilities.
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');
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
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'}
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()
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()
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
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
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()
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'; });
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
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.
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()
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 will receive the following arguments:
- Property Value (*)
- Key name (String)
- Target object (Object)
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']
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 will receive the following arguments:
- Property Value (*)
- Key name (String)
- Target object (Object)
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']
Returns a sorted list of all enumerable properties that have function values (including inherited properties).
var obj = {
foo : function(){},
bar : 'baz'
};
functions(obj); // ['foo']
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
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.
var a = {
b : {
c : 123
}
};
has(a, 'b.c'); // true
has(a, 'foo.c'); // false
if( has(a, 'foo.c') ){ // false
// ...
}
if( a.foo.c ){ // ReferenceError: `foo` is not defined
// ...
}
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
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.
var obj = {
foo : 1,
bar : 2,
lorem : 3
};
keys(obj); // ['foo', 'bar', 'lorem']
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 }
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()
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()
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'
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'
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.
target
(Object) : Target Object....objects
(...Object) : Objects to be combined (0...n objects).
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}
Creates an empty object inside namespace if not existent. Will return created object or existing object.
var obj = {};
namespace(obj, 'foo.bar'); // {}
console.log(obj); // {foo:{bar:{}}}
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'}
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"}
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} );
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
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()
var obj = {a: 1, b: 2, c: 3, d: 4, e: 5};
reject(obj, function(x) { return (x % 2) !== 0; }); // {b: 2, d: 4}
Returns an array of all own enumerable properties values found upon a given object.
PS: it won't return properties from the prototype.
var obj = {
foo : 1,
bar : 2,
lorem : 3
};
values(obj); // [1, 2, 3]
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}}
Returns the count of own enumerable properties found upon a given object.
PS: it won't return properties from the prototype.
var obj = {
foo : 1,
bar : 2,
lorem : 3
};
size(obj); // 3
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
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
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
Utilities for query string manipulation.
Checks if query string contains parameter.
url
(String) : URL or query string.paramName
(String) : Parameter name.
var url = 'example.com/?lorem=ipsum';
contains(url, 'lorem'); // true
contains(url, 'foo'); //false
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 object into a query string.
Will encode parameters with encodeURIComponent()
.
encode({foo: "bar", lorem: 123}); // "?foo=bar&lorem=123"
Get query parameter value.
Will typecast value with string/typecast
by default.
See: setParam()
url
(String) : Url.param
(String) : Parameter name.[shouldTypecast]
(Boolean) : If it should typecast value.
var url = 'example.com/?foo=bar&lorem=123&ipsum=false';
getParam(url, 'dolor'); // "amet"
getParam(url, 'lorem'); // 123
getParam(url, 'lorem', false); // "123"
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"}
Gets full query as string with all special chars decoded.
getQuery('example.com/?lorem=ipsum'); // "?lorem=ipsum"
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...
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.
Returns a random element from the supplied arguments or from an array if single argument is an array.
choice(1, 2, 3, 4, 5); // 3
var arr = ['lorem', 'ipsum', 'dolor'];
choice(arr); // 'dolor'
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.
guid(); // 830e9f50-ac7f-4369-a14f-ed0e62b2fa0b
guid(); // 5de3d09b-e79c-4727-932b-48c49228d508
Gets a random number inside range or snap to min/max values.
[min]
(Number) : Minimum value. Defaults tonumber/MIN_INT
.[max]
(Number) : Maximum value. Defaults tonumber/MAX_INT
.
rand(); // 448740433.55274725
rand(); // -31797596.097682
rand(0, 10); // 7.369723
rand(0, 10); // 5.987042
See: random()
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()
randBit(); // 1
randBit(); // 0
//same effect as
choice(0, 1);
Returns a random Boolean (true
or false
).
Since this is very common it makes sense to abstract it into a discrete method.
randBool(); // true
randBool(); // false
Returns a random hexadecimal string.
The default size
is 6
.
randHex(); // "dd8575"
randHex(); // "e6baeb"
randHex(2); // "a2"
randHex(30); // "effd7e2ad9a4a3067e30525fab983a"
Gets a random integer inside range or snap to min/max values.
[min]
(Number) : Minimum value. Defaults tonumber/MIN_INT
.[max]
(Number) : Maximum value. Defaults tonumber/MAX_INT
.
randInt(); // 448740433
randInt(); // -31797596
randInt(0, 10); // 7
randInt(0, 10); // 5
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()
randSign(); // -1
randSign(); // 1
//same effect as
choice(-1, 1);
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).
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.
Returns a random string.
By default returns string containing alphanumeric characters (lowercase and uppercase) with a length of 8.
[length]
(number) : Length of the string to return. Defaults to 8.[dictionary]
(string) : A string containing all characters used as a dictionary for the random string construction. Defaults to alphanumeric characters (lowercase and uppercase).
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 utilities.
Convert string to "camelCase" text.
See: pascalCase()
, unCamelCase()
camelCase('lorem-ipsum-dolor'); // "loremIpsumDolor"
camelCase('lorem ipsum dolor'); // "loremIpsumDolor"
Checks if string contains the given substring.
See: startsWith()
, endsWith()
contains('lorem', 'or'); // true
contains('lorem', 'bar'); // false
Truncate string at full words. Alias to truncate(str, maxChars, append, true);
.
See: truncate()
crop('lorem ipsum dolor', 10); // "lorem..."
crop('lorem ipsum dolor', 10, '+'); // "lorem+"
Checks if string ends with specified suffix.
See: startsWith()
, contains()
endsWith('lorem ipsum', 'lorem'); // false
endsWith('lorem ipsum', 'ipsum'); // true
Escapes the following special characters for use in HTML:
&
becomes&
<
becomes<
>
becomes>
'
becomes'
"
becomes"
No other characters are escaped. To HTML-escape other characters as well, use a third-party library like he.
See: unescapeHtml()
escapeHtml('lorem & "ipsum"'); // "lorem &amp; &quot;ipsum&quot;"
Escape special chars to be used as literals in RegExp constructors.
str = escapeRegExp('[lorem.ipsum]'); // "\\[lorem\\.ipsum\\]"
reg = new RegExp(str); // /\[lorem\.ipsum\]/
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"
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"
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"
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!"
"Safer" String.toLowerCase()
. (Used internally)
(null).toLowerCase(); // Error!
(undefined).toLowerCase(); // Error!
lowerCase(null); // ""
lowerCase(undefined); // ""
Pad string from left with char
if its' length is smaller than minLen
.
See: rpad()
lpad('a', 5); // " a"
lpad('a', 5, '-'); // "----a"
lpad('abc', 3, '-'); // "abc"
lpad('abc', 4, '-'); // "-abc"
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.
ltrim(' lorem ipsum '); // "lorem ipsum "
ltrim('--lorem ipsum--', ['-']); // "lorem ipsum--"
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()
makePath('lorem', 'ipsum', null, 'dolor'); // "lorem/ipsum/dolor"
makePath('foo///bar/'); // "foo/bar/"
Normalize line breaks to a single format. Defaults to Unix \n
.
It handles DOS (\r\n
), Mac (\r
) and Unix (\n
) formats.
// "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', ' ');
Convert string to "PascalCase" text.
See: camelCase()
pascalCase('lorem-ipsum-dolor'); // "LoremIpsumDolor"
pascalCase('lorem ipsum dolor'); // "LoremIpsumDolor"
UPPERCASE first char of each word, lowercase other chars.
properCase('loRem iPSum'); // "Lorem Ipsum"
Remove non-printable ASCII chars.
removeNonASCII('äÄçÇéÉêlorem-ipsumöÖÐþúÚ'); // "lorem-ipsum"
Remove non-word chars.
var str = 'lorem ~!@#$%^&*()_+`-={}[]|\\:";\'/?><., ipsum';
removeNonWord(str); // "lorem - ipsum"
Repeat string n-times.
repeat('a', 3); // "aaa"
repeat('bc', 2); // "bcbc"
repeat('a', 0); // ""
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.
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..."
Replaces all accented chars with regular ones.
Important: Only covers Basic Latin and Latin-1 unicode chars.
replaceAccents('spéçïãl çhârs'); // "special chars"
Pad string from right with char
if its' length is smaller than minLen
.
See: lpad()
rpad('a', 5); // "a "
rpad('a', 5, '-'); // "a----"
rpad('abc', 3, '-'); // "abc"
rpad('abc', 4, '-'); // "abc-"
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.
rtrim(' lorem ipsum '); // " lorem ipsum"
rtrim('--lorem ipsum--', ['-']); // "--lorem ipsum"
UPPERCASE first char of each sentence and lowercase other chars.
var str = 'Lorem IpSum DoLOr. maeCeNnas Ullamcor.';
sentenceCase(str); // "Lorem ipsum dolor. Maecennas ullamcor."
Remove HTML/XML tags from string.
var str = '<p><em>lorem</em> <strong>ipsum</strong></p>';
stripHtmlTags(str); // "lorem ipsum"
Checks if string starts with specified prefix.
See: endsWith()
, contains()
startsWith('lorem ipsum', 'lorem'); // true
startsWith('lorem ipsum', 'ipsum'); // false
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()
var str = 'loremIpsum dolor spéçïãl chârs';
slugify(str); // "loremipsum-dolor-special-chars"
slugify(str, '_'); // "loremipsum_dolor_special_chars"
Strip leading characters followed by 'marginChar' from every line in a String. The default margin character is a pipe.
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"
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.
trim(' lorem ipsum '); // "lorem ipsum"
trim('-+-lorem ipsum-+-', ['-', '+']); // "lorem ipsum"
Limit number of chars. Returned string length
will be <= maxChars
.
See: crop()
str
(String) : StringmaxChars
(Number) : Maximum number of characters includingappend.length
.[append]
(String) : Value that should be added to the end of string. Defaults to "...".[onlyFullWords]
(Boolean) : If it shouldn't break words. Default isfalse
. (favorcrop()
since code will be clearer).
truncate('lorem ipsum dolor', 11); // "lorem ip..."
truncate('lorem ipsum dolor', 11, '+'); // "lorem ipsu+"
truncate('lorem ipsum dolor', 11, null, true); // "lorem..."
Parses string and convert it into a native value.
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
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]
unCamelCase('loremIpsumDolor'); // "lorem ipsum dolor"
unCamelCase('loremIpsumDolor', '-'); // "lorem-ipsum-color"
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"
Unescapes the following HTML character references back into the raw symbol they map to:
&
becomes&
<
becomes<
>
becomes>
'
becomes'
"
becomes"
No other HTML character references are unescaped. To HTML-unescape other entities as well, use a third-party library like he.
See: escapeHtml()
unescapeHtml('lorem &amp; &quot;ipsum&quot;'); // 'lorem & "ipsum"'
Unescapes unicode char sequences.
See: escapeUnicode()
unescapeUnicode('\\u0066\\u00f8\\u006f\\u0020\\u0062\\u00e5\\u0072');
// > 'føo bår'
Replaces hyphens with spaces. (only hyphens between word chars)
See : hyphenate()
unhyphenate('lorem-ipsum-dolor'); // "lorem ipsum dolor"
"Safer" String.toUpperCase()
. (Used internally)
(null).toUpperCase(); // Error!
(undefined).toUpperCase(); // Error!
upperCase(null); // ""
upperCase(undefined); // ""
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...
Utilities for time manipulation.
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
Returns the number of milliseconds elapsed since 1 January 1970 00:00:00 UTC.
Uses Date.now()
if available.
now(); // 1335449614650
Parse timestamp (milliseconds) into an object {milliseconds:number, seconds:number, minutes:number, hours:number, days:number}
.
// {days:27, hours:4, minutes:26, seconds:5, milliseconds:454}
parseMs(2348765454);
Convert timestamp (milliseconds) into a time string in the format "[H:]MM:SS".
toTimeString(12513); // "00:12"
toTimeString(951233); // "15:51"
toTimeString(8765235); // "2:26:05"
_Resources/node_modules/mout/
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.
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.
- 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);
- 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...
Online documentation can be found at http://moutjs.com/ or inside the
doc
folder.
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
Released under the MIT License.
_Resources/node_modules/web-dev-utils/GIT-HTML-PREVIEW-TOOL/GIT-HTML-PREVIEW-TOOL-master/
TOC
About ● How It Works ● Development ● Contact
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
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.
<a target="_blank" rel="noopener noreferrer"target="_blank" rel="noopener noreferrer"href="https://githtmlpreview.netlify.app/">[Live Website]
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.
(Full-stack software developer)
<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>
(() => {
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.
One to two paragraph statement about your product and what it does.
OS X & Linux:
npm install my-crazy-module --save
Windows:
edit autoexec.bat
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.
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
- 0.2.1
- CHANGE: Update docs (module code remains unchanged)
- 0.2.0
- CHANGE: Remove
setDefaultXYZ()
- ADD: Add
init()
- CHANGE: Remove
- 0.1.1
- FIX: Crash when calling
baz()
(Thanks @GenerousContributorName!)
- FIX: Crash when calling
- 0.1.0
- The first proper release
- CHANGE: Rename
foo()
tobar()
- 0.0.1
- Work in progress
Your Name – @YourTwitter – YourEmail@example.com
Distributed under the XYZ license. See LICENSE
for more information.
https://github.com/yourname/github-link
- Fork it (https://github.com/yourname/yourproject/fork)
- Create your feature branch (
git checkout -b feature/fooBar
) - Commit your changes (
git commit -am 'Add some fooBar'
) - Push to the branch (
git push origin feature/fooBar
) - Create a new Pull Request
project_description
Explore the docs »
View Demo
·
Report Bug
·
Request Feature
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
To get a local copy up and running follow these simple steps.
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
- Clone the repo
git clone https://github.com/github_username/repo_name.git
- Install NPM packages
npm install
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
See the open issues for a list of proposed features (and known issues).
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.
- Fork the Project
- Create your Feature Branch (
git checkout -b feature/AmazingFeature
) - Commit your Changes (
git commit -m 'Add some AmazingFeature'
) - Push to the Branch (
git push origin feature/AmazingFeature
) - Open a Pull Request
Distributed under the MIT License. See LICENSE
for more information.
Your Name - @twitter_handle - email
Project Link: https://github.com/github_username/repo_name
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.
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>
.
To install <project_name>, follow these steps:
Linux and macOS:
<install_command>
Windows:
<install_command>
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!
To contribute to <project_name>, follow these steps:
- Fork this repository.
- Create a branch:
git checkout -b <branch_name>
. - Make your changes and commit them:
git commit -m '<commit_message>'
- Push to the original branch:
git push origin <project_name>/<location>
- Create the pull request.
Alternatively see the GitHub documentation on creating a pull request.
Thanks to the following people who have contributed to this project:
- @bgoonz 📖
- @cainwatson 🐛
- @calchuchesta 🐛
You might want to consider using something like the All Contributors specification and its emoji key.
If you want to contact me you can reach me at your_email@address.com.
This project uses the following license: <license_name>.
_Resources/node_modules/web-dev-utils/Markdown-Templates/Markdown-Templates-master/notes-template.md
- Description:
/* Description here */
<a target="_blank" rel="noopener noreferrer"target="_blank" rel="noopener noreferrer"name="headers"/>
# H1
## H2
### H3
#### H4
##### H5
###### H6
Alternatively, for H1 and H2, an underline-ish style:
Alt-H1
======
Alt-H2
------
Alternatively, for H1 and H2, an underline-ish style:
<a target="_blank" rel="noopener noreferrer"target="_blank" rel="noopener noreferrer"name="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"/>
(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
- First ordered list item
- Another item
- Unordered sub-list.
-
Actual numbers don't matter, just that it's a number
-
Ordered sub-list
-
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"/>
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 with title
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"/>
Here's our logo (hover to see the title text):
Inline-style:

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):
<a target="_blank" rel="noopener noreferrer"target="_blank" rel="noopener noreferrer"name="code"/>
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 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 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"/>
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"/>
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"/>
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"/>
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:
[](http://www.youtube.com/watch?v=YOUTUBE_VIDEO_ID_HERE)
One Paragraph of project description goes here
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.
What things you need to install the software and how to install them
Give examples
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
Explain how to run the automated tests for this system
Explain what these tests test and why
Give an example
Explain what these tests test and why
Give an example
Add additional notes about how to deploy this on a live system
- Dropwizard - The web framework used
- Maven - Dependency Management
- ROME - Used to generate RSS Feeds
Please read CONTRIBUTING.md for details on our code of conduct, and the process for submitting pull requests to us.
We use SemVer for versioning. For the versions available, see the tags on this repository.
- Bryan Guner - Initial work - bgoonz
See also the list of contributors who participated in this project.
This project is licensed under the MIT License - see the LICENSE.md file for details
- Hat tip to anyone whose code was used
- Inspiration
- etc
TOC
About ● Features ● How It Works ● Installation ● Development ● Contact
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.
##Try the Demo! <a target="_blank" rel="noopener noreferrer"target="_blank" rel="noopener noreferrer"href="">[Live Website]
● See Website ●
(Inspired by app name)
Describe overview of app, themes and philosophy, inspiration, audience, or whatever... 1-2 paragraphs
- 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
- 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!
- A list
- could be
- nice too
Header A Header B A B
##How to Use Feature ABC Repeat the pattern.
##Troubleshooting Z Repeat the pattern.
- Create a new postgres database and owner.
- Create a
.env
file matching the.env.example
file and your new postgres information. - Migrate the database with
npx sequelize-cli db:migrate
. - Seed the migration with
npx sequelize-cli db:seed:all
. - Run locally with
npm start
.
##Get started on Heroku - Account, Database, Config Vars
- Install the Heroku CLI, if you haven't done so already.
- Create a free Heroku account.
- Login and create a new Heroku app.
- Navigate to the Resources tab an set up a 'Heroku Postgres' database for the app.
- Select the 'Hobby Dev - Free' plan.
- 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
, andDB_DATABASE
arent' required.
##Configure the app to use the Heroku Postgres database
There are two ways to configure the production
environment:
- With dotenv and a
.sequelizerc
file that points to aconfig/database.js
file. - 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"
}
- In the root of the app's repo directory, log into Heroku with
heroku login
. - Add a new remote to GitHub configuration with
heroku git:remote -a <<app-name-here>>
. - Add all changes with
git add .
. - Commit changes with
git commit -m "<<Add message here>>"
. (Optionally,git commit -am
Adds and commits in one command.) - Push changes to Heroku with
git push Heroku
. - 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
- To migrate your Heroku Postgres database, run the migration command prefaced with
heroku run
inside the repo.
heroku run npx sequelize-cli db:migrate
- To seed, preface the seed command with
heroku run
as well.
heroku run npx sequelize-cli db:seed:all
- 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
DEV TOC
Technologies ● Concept ● Models ● Routes ● Wireframes ● Code Highlights ● Dev 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.
Thank you very much for your interest in this project.
Feel free to reach out to provide feedback, bug reports, or anything else :) .
##Bryan Guner (Full-stack software developer)
<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>
_Resources/node_modules/web-dev-utils/Markdown-Templates/Markdown-Templates-master/Standard-Project-README.md
An awesome README template to jumpstart your projects!
Explore the docs »
View Demo
·
Report Bug
·
Request Feature
Table of Contents
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.
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.
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.
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
- Get a free API Key at https://example.com
- Clone the repo
git clone https://github.com/your_username_/Project-Name.git
- Install NPM packages
npm install
- Enter your API in
config.js
const API_KEY = 'ENTER YOUR API';
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
See the open issues for a list of proposed features (and known issues).
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.
- Fork the Project
- Create your Feature Branch (
git checkout -b feature/AmazingFeature
) - Commit your Changes (
git commit -m 'Add some AmazingFeature'
) - Push to the Branch (
git push origin feature/AmazingFeature
) - Open a Pull Request
Distributed under the MIT License. See LICENSE
for more information.
Your Name - @your_twitter - email@example.com
Project Link: https://github.com/your_username/repo_name
_Resources/node_modules/web-dev-utils/personal-utilities/copy-2-clip/
$(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
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
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/
TOC
About ● Features ● How It Works ● Installation ● Development ● Contact
- Duplicate Remover (duplicate lines... Case and whitespace sensative)
- Find and Replace
- 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.
- Add Prefix/Suffix (by line.. not by file)
- White Space remover (It removes all the whitespace within your text. I use it for creating javascript for iMacros for Firefox)
- Sort Text Lines (It sorts text lines alphabetically in ascending and descending order)
- 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.)
- 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)
<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>

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 printCombinations
that 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 printCombinations
that 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/
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
- If you already have VSCode open, close it.
- On your computer's Desktop, create a new folder named
my-first-programs
.
- Open the
my-first-programs
folder in VSCode
- Use VSCode to create a file named
greeting.js
inside of my-first-programs
.
- 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.
- Save the
greeting.js
file using the keyboard shortcut cmd + s
or ctrl + s
.
- Open the terminal and enter the command
node greeting.js
to execute your code. You should see
hello world
printed out.
- Inside the
my-first-programs
folder, create a new file named whoami.js
.
- 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 (;
).
- Save
whoami.js
and execute it in your terminal using the node
. You should see your name
printed out.
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.
That seems suspicious. Write a program named age.js
that prints out your age. Run it.
javascript-practice/00_expressions_variables/exercises/B_expressions_exercise/
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
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
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.
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);
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));
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);
javascript-practice/00_expressions_variables/exercises/C_variables_exercise/
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
Create a folder named variables_exercise
. Create a file named zero.js
inside of it. Predict what
the console.log
s 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.
Create a new file named one.js
inside of the variables_exercise
folder. Predict what the
console.log
s 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.
Create a new file named two.js
inside of the variables_exercise
folder. Predict what the
console.log
s in the code below will print out:
let apple;
console.log(apple);
apple = 5;
console.log(apple);
apple + 1;
console.log(apple);
apple