var cornChip = {
sound: "crunch",
eat: function() {
console.log(this.sound);
},
}
console.log(cornChip.eat());
var potatoChip = {
sound: "crackle",
eat: cornChip.eat,
}
console.log(potatoChip.eat());Javascript Examples
Thursday, July 20, 2017
Crunch or Crackle?
Will the potato chip crunch or crackle?
Saturday, July 1, 2017
forEach() with filter() Lookup
Let's avoid some data duplication and use a keyed lookup to retrieve a book's author.
class Author {
constructor(name, birth, death, nationality) {
this.name = name,
this.birth = birth,
this.death = death,
this.nationality = nationality
}
}
class Book {
constructor(title, pubDate, authorKey) {
this.title = title,
this.pubDate = pubDate,
this.authorKey = authorKey
}
}
authors = [
new Author({first: "William", last: "Shakespeare"}, 1564, 1616, "English"),
new Author({first: "Francis", last: "Bacon"}, 1561, 1626, "English"),
new Author({first: "Thomas", last: "More"}, 1478, 1535, "English"),
new Author({first: "Geoffrey", last: "Chaucer"}, 1343, 1400, "English"),
new Author({first: "Mary", last: "Shelley"}, 1797, 1851, "English"),
new Author({first: "Jane", last: "Austen"}, 1775, 1817, "English"),
new Author({first: "JK", last: "Rowling"}, 1965, 0, "English"),
new Author({first: "George", last: "Orwell"}, 1797, 1851, "English"),
new Author({first: "Charles", last: "Dickens"}, 1797, 1851, "English"),
new Author({first: "George", last: "Eliot"}, 1819, 1880, "English")
];
books = [
new Book("Middlemarch", 1871, 9),
new Book("Silas Marner", 1861, 9),
new Book("A Christmas Tale", 1843, 8),
new Book("Oliver Twist", 1837, 8),
new Book("Great Expectations", 1860, 8),
new Book("A Tale of Two Cities", 1859, 8),
new Book("David Copperfield", 1849, 8),
new Book("Nineteen Eighty-Four", 1949, 7),
new Book("Animal Farm", 1945, 7),
new Book("The Complete Plays", 2016, 1),
new Book("Four Great Comedies", 2009, 1),
new Book("Essays", 1597, 1),
new Book("Novum Organum Scientiarum", 1620, 1),
new Book("A Merry Jest ", 1516, 2),
new Book("Utopia", 1516, 2),
new Book("The Canterbury Tales", 1400, 3),
new Book("Frankenstein: or, The Modern Prometheus", 1818, 4),
new Book("Sense and Sensibility ", 1811, 5),
new Book("Pride and Prejudice ", 1813, 5),
new Book("Harry Potter and the Philosopher's Stone ", 1997, 6),
new Book("Harry Potter and the Chamber of Secrets", 1998, 6),
new Book("Harry Potter and the Prisoner of Azkaban", 1999, 6),
new Book("Harry Potter and the Goblet of Fire", 2000, 6),
];
for (let i = 0; i < books.length; i++) {
let auth = authors.filter( (elem, index) => books[i].authorKey === index);
console.log(`title: ${books[i].title}, author: ${auth[0].name.first} ${auth[0].name.last}`);
};
books.forEach((book, index) => {
let auth = authors.filter( (elem, i) => book.authorKey === i);
console.log(`title: ${book.title}, author: ${auth[0].name.first} ${auth[0].name.last}`);
});
Wednesday, June 28, 2017
JS Basics
Obj literal, Constructor, Class and Properties
'use strict';
// object literal
var cat = {name: 'Fluffy', color: 'white'}
console.log(cat.color)
cat.age = 3
console.log('name=' + cat.name + ' and age=' + cat.age)
cat.speak = function() {console.log('Meoow')}
cat.speak()
// constructor
function Cat2(name, color) {
this.name = name,
this.color = color
}
var sam = new Cat2('Sam', 'tabby');
console.log(sam.color)
// class
class Cat3 {
constructor(name, color, age) {
this.name = name,
this.color = color,
this.age = age
}
speak() {
console.log('Meoow')
}
}
var fred = new Cat3({first: 'Frederico', last: 'DeSoto'},'silver', 5)
fred.speak()
for (let property in fred) {
console.log(property + ": " + fred[property])
}
console.log(JSON.stringify(fred));
Object.defineProperty(fred, 'fullName',
{
get: function() {
return this.name.first + " " + this.name.last
},
set: function(val) {
let parts = val.split(' ');
this.name.first = parts[0];
this.name.last = parts[1];
}
})
console.log(fred.fullName)
fred.fullName = 'George Smiley'
console.log(fred.fullName) // George Smiley
Tuesday, June 27, 2017
Screen Scraping
I wanted a list of the episode titles of "Agatha Christie's Poirot", my favorite TV detective series. I decided to scrape the HTML from wikipedia's entry. The data looks like this:
I found a Javascript library named cheerio that seemed to do what I require.
<tr> <th scope="row" style="text-align:center;"><a href="/wiki/Poirot%27s_Early_Cases#The_Adventure_of_the_Clapham_Cook" title="Poirot's Early Cases">The Adventure of the Clapham Cook</a></th> <td style="text-align:center;">8 January 1989</td> <tr> <th scope="row" style="text-align:center;"><a href="/wiki/Murder_in_the_Mews_(TV_1989)" class="mw-redirect" title="Murder in the Mews (TV 1989)">Murder in the Mews</a></th> <td style="text-align:center;">15 January 1989</td>I want the text from the <a> tag that resides inside the <th> tag.
I found a Javascript library named cheerio that seemed to do what I require.
$ npm install request cheerio
// index.js
let request = require('request');
let cheerio = require('cheerio');
let lastEpisode = false;
request({
uri: "https://en.wikipedia.org/wiki/List_of_Agatha_Christie's_Poirot_episodes"
}, function (err, response, html) {
if (err || response.statusCode !== 200) {
console.log('E R R O R ' + response.statusCode);
return;
}
var $ = cheerio.load(html);
$('th a').each(function(i, elem) {
let episode = $(this).text();
// eliminate "[fn" (footnotes)
if (!lastEpisode && episode.substring(0, 3) !== '[fn') {
console.log(episode);
}
lastEpisode = lastEpisode || (episode.substring(0, 7) === "Curtain");
});
});
$ node index.js The Adventure of the Clapham Cook Murder in the Mews The Adventure of Johnnie Waverly Four and Twenty Blackbirds The Third Floor Flat Triangle at Rhodes Problem at Sea The Incredible Theft The King of Clubs The Dream Peril at End House The Veiled Lady The Lost Mine The Cornish Mystery The Disappearance of Mr. Davenheim Double Sin The Adventure of the Cheap Flat . . . Cat Among the Pigeons Third Girl Appointment with Death Three Act Tragedy Hallowe'en Party Murder on the Orient Express The Clocks Elephants Can Remember The Big Four Dead Man's Folly The Labours of Hercules Curtain: Poirot's Last Case
Functional Array Processing
Write a function that will search an array of integers for two values that equal 2nd argument.
let arrayInput = [3, 34, 4, 12, 5, 2];
// function to find two values in inputArray that equal target
function findPairForSum(integers, target) {
let result = [];
var subtree = (givenArray, el2Eliminate) => {
let copy = [];
givenArray.forEach( (el, i, ar) => {
if (i !== el2Eliminate) {
copy.push(el);
}
});
return copy;
}
integers.forEach( (el, i, ar) => {
let eliminate = i;
let choppedArray = subtree(ar, i);
choppedArray.forEach( (el, i, ar) => {
if (eliminate + el == target) {
result.push(eliminate);
result.push(el);
return result;
}
});
});
return result;
}
// test 1
var pair = findPairForSum(arrayInput, 9);
console.log(`9 = ${pair}`); // --> [4, 5]
// test 2
pair = findPairForSum(arrayInput, 14);
console.log(`14 = ${pair}`); // --> [12, 2]
// test 3
pair = findPairForSum(arrayInput, 99);
console.log(`99 = ${pair}`); // --> [,]Javascript Shortcuts
Creating a new function as shown in the receive function in the first clock of code creates a new lexical scope, a new 'this', which necessitates 'var that = this;'.
Lambdas do not create a new lexical scope, ie, lexical scope is retained when using lambdas.
Eliminate that = this; code and avoid having to deal with changes to lexical scope by using lambdas.
Replace function(message) with message => to define the lambda.
Lambdas do not create a new lexical scope, ie, lexical scope is retained when using lambdas.
Old Style
Old style Javascript without lambdas requires use of that = this;.let screenObj = {
name: "Button",
handleMessage: function(message, handler) {
handler(message);
},
receive: function(greeting) {
var that = this;
this.handleMessage(greeting, function(message) {
console.log(message + that.name)
})
}
};
screenObj.receive("Hello, "); // Hello, Button
Replace function(message) with message => to define the lambda.
let screenObj = {
name: "Button",
handleMessage: function(message, handler) { handler(message)},
receive: function(greeting) {
this.handleMessage(greeting,
message => console.log(message + this.name))
}
};
screenObj.receive("Hello, "); // Hello, Button
Simplifying
let first = 'Johnnie'
let last = 'Cash'
// this definition can be simplified
const firstAndLast = { first: first, last: last }
console.log(firstAndLast.last) // Cash
// name only the keys
const firstLast = { first, last }
console.log(firstLast.last) // Cash
Spread Operator
const odd = [1, 3, 5]; const even = [2, 4, 6]; const nums = [...even, ...odd]; // [2, 4, 6, 1, 3, 5]
The Import Statement
const foo = require('blah/foo');
const bar = require('blah/bar');
// can be replaced with
import {foo, bar} from 'blah';
Default Parameters
let noDefaults = function(greeting, name) {
console.log(`${greeting}, ${name}`);
}
let withDefaults = function(greeting="Hello", name="George") {
console.log(`${greeting}, ${name}`);
}
noDefaults(); // undefined, undefined
withDefaults("Hi", "Joe"); // Hi, Joe
withDefaults(); // Hello, George
Destructuring an Array
let names = ['Charles', 'Debbie', 'Susan', 'Keith'] var [boy1,,,boy2] = names console.log(boy1) // Charles console.log(boy2) // Keith
Destructuring an Object
let managerie = () => {
return {
dog: 'terrier',
cat: 'tabby',
fish: 'shark',
bird: 'parrot',
}
};
let {dog, fish} = managerie();
console.log(dog); // terrier
console.log(fish); // shark
Destructuring an Object in the Argument List
let sneakers = [
{
name: 'Air Jordans',
brand: 'Nike',
},
{
name: 'Flyers',
brand: 'Converse',
},
{
name: 'Runners',
brand: 'Sketchers',
},
{
name: 'Trail Runner',
brand: 'New Balance',
}];
let [,,cheapShoe] = sneakers
let log = function({brand}) { // destructure the object passed
console.log(brand)
}
log(cheapShoe) // Sketchers
ES6 Generators
function*, yield and next()function* repeat() {
const arr = ["A", "B", "C", "D"];
for (let x in arr) {
yield arr[x];
}
}
var foo = repeat();
let bar = foo.next();
while (!bar.done) {
console.log(bar.value); // logs a letter with each iteration
bar = foo.next();
}
The Array.reduce Function
let votes=['react','react','react','vue','meteor','angular','angular']
let voteCount = function(tally, vote) {
if (!tally[vote]) {
tally[vote] = 1
} else {
tally[vote] += 1
}
return tally
}
let results = votes.reduce(voteCount, {})
for (framework in results) {
console.log(framework + "=" + results[framework])
}
// react=3
// vue=1
// meteor=1
// angular=2
Map and Reduce
const data = ["a", "b","c"]
let doubled = data.reduce(function(acc, elem) {
acc.push(elem + elem)
return acc;
}, []);
let doubleMapped = data.map(function(elem) {
return elem + elem;
});
let filterMapped = data.filter(function(elem) {
return elem !== "b";
}).map(function(elem) {
return elem + elem.toUpperCase();
});
console.log(doubled) // [aa,bb,cc]
console.log(doubleMapped) // [aa,bb,cc]
console.log(filterMapped) // [aA,cC]
Saturday, December 17, 2016
Rediscovering Javascript by Venkat Subramaniam
Venkat is brilliant https://youtu.be/r9XAp3CWRf4?t=30m14s
Using the Implicit Context Object
var greet = function(name) {
console.log(this.toUpperCase() + ' ' + name);
}
// greet('Joe'); // blows up
greet.call('hello', 'Joe'); // 'hello' becomes the implicit 'this'
> HELLO JoeUsing Arguments Array and Apply
var greet = function(name1, name2) {
console.log(this.toUpperCase() + ' ' + name1 + ' ' + name2);
}
greet.apply('hi', ['Jack', 'Jill']);
> HI Jack JillThursday, December 15, 2016
React Elements vs React Components
React Elements vs React Components reveals how React renders elements and components. The way properties can be code or data gives Javascript a flavor of LISP's homoinconicity.
Javascript ORM
TypeORM a Data-Mapper ORM for TypeScript, ES7, ES6 and ES5. Supports MySQL, PostgreSQL, MariaDB, SQLite, MS SQL Server, Oracle databases.
Wednesday, December 14, 2016
Accumulate Array of Arrays Using forEach
Flatten - Combining Arrays with forEach()
var data = [[1,2,3], [4,5,6], [7,8,9]];
function arrayAdd(aOfAs) {
var acc = [];
aOfAs.forEach(function(a) {
a.forEach(function(el) {
acc.push(el);
;})
;});
return acc;
}
arrayAdd(data);
> [1,2,3,4,5,6,7,8,9]Same Thing - Flatten with reduce()
var data = [[1,2,3],[4,5,6],[7,8,9]];
var flattenedData = data.reduce(function(acc, value) {
return acc.concat(value);
}, []);
console.log(flattenedData);
> [1, 2, 3, 4, 5, 6, 7, 8, 9]Processing every element of an array with reduce()
var data = [1,2,3,4,5];
var doubled = data.reduce(function(acc, value) {
acc.push(value * 2);
return acc;
}, []);
console.log(doubled);
> [2, 4, 6, 8, 10]Selecting some elements of an array with reduce()
var data = [1,2,3,4,5];
var evens = data.reduce(function(acc, value) {
if (value % 2 === 0) {
acc.push(value);
}
return acc;
}, []);
console.log(evens);
> [2, 4]Same Thing Using filter()
var evenFiltered = data.filter(function(item) {
return item % 2 === 0;
});
console.log(evenFiltered);
[2, 4]Filtered and Mapped
var filteredAndMapped = data.filter(function(value) {
return value % 2 == 0;
}).map(function(value) {
return value * 2;
});
console.log(filteredAndMapped);
> [4, 8]Array's Functional Functions
What is the difference between Array's functions .map, .every, and .forEach?
.map() returns a new Array of objects created by taking some action on the original item.
.every() returns a boolean - true if every element in this array satisfies the provided testing function. An important difference with .every() is that the test function may not always be called for every element in the array. Once the testing function returns false for any element, no more array elements are iterated. Therefore, the testing function should usually have no side effects.
.forEach() returns nothing - It iterates the Array performing a given action for each item in the Array.
.map() returns a new Array of objects created by taking some action on the original item.
.every() returns a boolean - true if every element in this array satisfies the provided testing function. An important difference with .every() is that the test function may not always be called for every element in the array. Once the testing function returns false for any element, no more array elements are iterated. Therefore, the testing function should usually have no side effects.
.forEach() returns nothing - It iterates the Array performing a given action for each item in the Array.
First Job Red Flags for the New Javascript Developer
You attended a coding bootcamp, paying more than $10,000 for the privilege and now you are on the cusp of starting your new career. Do you value the education you received? Your new employer will certainly be happy to get you and they will think they are training you in a way that continues the progress you've made but, good intentions are sometimes mixed with ignorance. What are the indications your potential employer is going to detour you to a dead-end?
The Programmer's Bill of Rights on Coding Horror is inadequate for determining if a job will be a good one. Based on my own experience and observations, I created a list of indicators of a bad IT developer job.
Red Flags
No source control
No unit test, no automated unit tests
No automated build
No application spec
No code reviews
No bug database
Not asked to code or whiteboard on the interview
Wants you to focus on the backend
No control over your development machine
Has a mainframe or similar
Is an Oracle or IBM shop [1.]
uses a language your grandpa might have used if he were a developer
uses or desires to use a rules engine
uses stored procedures (you may want to stay away from SQL and relational DBs completely)
uses failed Java stuff - EJBs, Websphere, JEE, JSF, Eclipse
Really Red Flag
An old school shop wants to hire you as the first person in a planned cardre of developers with modern skills [2.]
Green Flags
none of the red flags
Your job includes:
- pair programming
- coding in functional language & functional style
- working on UI and on distributed services
- working with users to spec and develop from new requirements
[1.] if you work where they invest in 1980s or 1990s technology, the people who know the old stuff will be the most highly rewarded people there and they are rewarded largely for fixing their own mistakes. Their Friday installs will result in Saturday and Sunday all-hands conference calls that will screw-up your weekends and on Monday they will get an 'atta-boy' for fixing their bug. See Flintstoning
[2.] if the shop cannot evolve with the developers they have then they cannot evolve so don't be the victim of their history of rationalizations and laziness.
The Programmer's Bill of Rights on Coding Horror is inadequate for determining if a job will be a good one. Based on my own experience and observations, I created a list of indicators of a bad IT developer job.
Red Flags
No source control
No unit test, no automated unit tests
No automated build
No application spec
No code reviews
No bug database
Not asked to code or whiteboard on the interview
Wants you to focus on the backend
No control over your development machine
Has a mainframe or similar
Is an Oracle or IBM shop [1.]
uses a language your grandpa might have used if he were a developer
uses or desires to use a rules engine
uses stored procedures (you may want to stay away from SQL and relational DBs completely)
uses failed Java stuff - EJBs, Websphere, JEE, JSF, Eclipse
Really Red Flag
An old school shop wants to hire you as the first person in a planned cardre of developers with modern skills [2.]
Green Flags
none of the red flags
Your job includes:
- pair programming
- coding in functional language & functional style
- working on UI and on distributed services
- working with users to spec and develop from new requirements
[1.] if you work where they invest in 1980s or 1990s technology, the people who know the old stuff will be the most highly rewarded people there and they are rewarded largely for fixing their own mistakes. Their Friday installs will result in Saturday and Sunday all-hands conference calls that will screw-up your weekends and on Monday they will get an 'atta-boy' for fixing their bug. See Flintstoning
[2.] if the shop cannot evolve with the developers they have then they cannot evolve so don't be the victim of their history of rationalizations and laziness.
Monday, December 12, 2016
Recursion on Sorted Array
Find if any two elements in a sorted array can equal a sum.
Write a function checkSumOf2 that accepts two parameters, a sorted array and a number that is the target that two numbers in the array should sum to.
Write a function checkSumOf2 that accepts two parameters, a sorted array and a number that is the target that two numbers in the array should sum to.
function checkSumOf2(ary, target) {
function check2(ary, target, left, right) {
if (left >= right) {
return false;
}
var sum = ary[left] + ary[right];
if (sum === target) {
return true;
} else if (sum > target) {
right--;
} else {
left++;
}
return check2(ary, target, left, right);;
}
return check2(ary, target, 0, ary.length - 1);
}
console.log( '1.' + checkSumOf2([1,3,5,7], 8) ) // true
console.log( '2.' + checkSumOf2([0,2,6,8], 7) ) // false
console.log( '3.' + checkSumOf2([4,5,6,7], 12) ) // true
console.log( '4.' + checkSumOf2([1,2,3,4], 12) ) // false
console.log( '5.' + checkSumOf2([1,2,3,4], 4) ) // true
Thursday, November 17, 2016
Recursive Problems
The lecture included a statement which was very helpful in solving all the recursive assignments, that the function will consist of two parts,
· the if clause that produces the termination of the recursive calls
· the recursive call
The structure that statement describes was the template we used in all of our solutions.
The problem statement in the Fibonacci exercise gave us another tool that we reused in subsequent exercises, a chart of the values of the function's fields over the steps of the recursive call. Although we had these tools that were useful later, we had to ask for help and Garrett coached us to the solution.
The problem statement tells us that for n > 1, fib(n) is fib(n - 1) + fib(n - 2)
What follows is the chart given to us in the problem then the Fibonicci function, followed by a version of the Fibonicci function that includes some logging statements. The console.log statements provide a view into the functioning of the function.
What allowed us to complete the problems was our willingness to try something we were pretty sure would not work and then diagnose the non-working code to determine the necessary changes.
1. Return statements that rely only on the function call:
· return fib(n - 1) + fib(n - 2);
· return isEven(n - 2);
· return add(dec(x), inc(y));
2. Return statements that rely on the function call plus values outside of the recursive call to the function:
· return start + sum(start + 1, end);
· return y + multiply(x - 1, y);
· return start * product(start + 1, end);
· the if clause that produces the termination of the recursive calls
· the recursive call
The structure that statement describes was the template we used in all of our solutions.
The problem statement in the Fibonacci exercise gave us another tool that we reused in subsequent exercises, a chart of the values of the function's fields over the steps of the recursive call. Although we had these tools that were useful later, we had to ask for help and Garrett coached us to the solution.
The problem statement tells us that for n > 1, fib(n) is fib(n - 1) + fib(n - 2)
What follows is the chart given to us in the problem then the Fibonicci function, followed by a version of the Fibonicci function that includes some logging statements. The console.log statements provide a view into the functioning of the function.
What allowed us to complete the problems was our willingness to try something we were pretty sure would not work and then diagnose the non-working code to determine the necessary changes.
Flavors of Recursive Functions
After receiving help from an instructor, we found that return statements in recursive functions come in two flavors:1. Return statements that rely only on the function call:
· return fib(n - 1) + fib(n - 2);
· return isEven(n - 2);
· return add(dec(x), inc(y));
2. Return statements that rely on the function call plus values outside of the recursive call to the function:
· return start + sum(start + 1, end);
· return y + multiply(x - 1, y);
· return start * product(start + 1, end);
Wednesday, November 16, 2016
DeMorgans Problem
// Write a function or that works like ||, but only uses ! and &&.
// Write a function OR that takes two Boolean values and returns
// a Boolean value such that it is not true that both are false
// ... i.e., one or the other or both
function OR(val1, val2) {
return !(!val1 && !val2);
}
function testDeMorgans(val1, val2) {
return (val1 || val2) === OR(val1, val2);
}
testDeMorgans(true, true); // returns true meaning OR function === ||
testDeMorgans(true, false);
testDeMorgans(false, false);
Subscribe to:
Posts (Atom)