Chapter 4 Data Structures: Objects and Arrays

“On two occasions I have been asked, ‘Pray, Mr. Babbage, if you put into the machine wrong figures, will the right answers come out?’ […] I am not able rightly to apprehend the kind of confusion of ideas that could provoke such a question.” — Charles Babbage, Passages from the Life of a Philosopher (1864)

Calculate Phi Coefficient

http://www.pmean.com/definitions/phi.htm

Sample intepretation

-1.0 to -0.7 strong negative association.

-0.7 to -0.3 weak negative association.

-0.3 to +0.3 little or no association.

+0.3 to +0.7 weak positive association.

+0.7 to +1.0 strong positive association.

We can interpret a, b, c, d as [a, b, c, d].

function phi (a, b, c, d) {

const numerator = a * d - b * c;

const denominator = Math.sqrt((a + b) * (c + d) * (a + c) * (b + d));

return (numerator/denominator).toFixed(2);

}

Further arraylogy

// Remove an item from an array function removeItem (array, item) {

let index = array.indexOf(item);

if (index >= 0) {

array = removeItemAtIndex(array, index);

}

} function removeItemAtIndex (array, index) {

return array.slice(0, index).concat(array.slice(index + 1));

}

There’s a real cool program idea given in the book:

var todoList = []; function rememberTo (task) {

todoList.push(task);

} function whatIsNext () {

return todoList.shift();

} function urgentlyRememberTo (task) {

todoList.unshift(task);

}

This gave me an idea and I spend half a day building a sample app. Here it is: https://github.com/gitfaf/sample-chrome-extension-todo-list

It’s a sample chrome extension that doesn’t do much; you can contribute. Let’s make it big.

Strings and their properties

The values are immutable and cannot be changed. This is a weird thing about JS. Even though you can slap a quick property and value to a string variable, it doesn’t stick to it.

var name = 'Git Faf';

name.value = 'GitFaf';

console.log(name.value); // undefined

console.log(name); // Git Faf

There’s this weird line in the book:

One difference is that a string’s indexOf can take a string containing more than one character, whereas the corresponding array method looks only for a single element.

var str = "Git Faf is my name";

str.indexOf('Faf'); // 4 var arr = str.split(' ');

arr.indexOf('Faf'); // 1

I mean, it makes sense to me and is intuitive too. Let me know if I missed something here.

Things that I would have liked to see here in the book:

// Convert string to array

var workweekString = 'Monday, Tuesday, Wednesday, Thursday, Friday';

var workweekArray = workweekString.split(', ');

console.log(workweekArray);

// (5) ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday"] // Convert array to string

var squishedWorkweekString = workweekArray.join('-');

console.log(squishedWorkweekString);

// Monday-Tuesday-Wednesday-Thursday-Friday // Convert a string to a character array

var charArray = squishedWorkweekString.split(''); // empty string as param

console.log(charArray);

// (40) ["M", "o", "n", "d", "a", "y", "-", "T", "u", "e", "s", "d", "a", "y", "-", "W", "e", "d", "n", "e", "s", "d", "a", "y", "-", "T", "h", "u", "r", "s", "d", "a", "y", "-", "F", "r", "i", "d", "a", "y"]

The arguments object

arguments is a special object that is created whenever a function is invoked for that function; it is accessible inside that function; it’s type is ArrayLike.

MDN: “array-like objects (objects with a length property and indexed elements)”

function any () {

console.log(arguments);

} any();

// [callee: ƒ, Symbol(Symbol.iterator): ƒ] any(1, 2, 3);

// (3) [1, 2, 3, callee: ƒ, Symbol(Symbol.iterator): ƒ] any({a: 1, b: 2, c: 3});

// [{…}, callee: ƒ, Symbol(Symbol.iterator): ƒ] any([1, 2, 3, 4]);

// [Array(4), callee: ƒ, Symbol(Symbol.iterator): ƒ] any(1, 2, 3, {a: 1, b: 2, c: 3}, [1, 2, 3, 4]);

// (5) [1, 2, 3, {…}, Array(4), callee: ƒ, Symbol(Symbol.iterator): ƒ]

You can get an actual array from arguments array using Array.from(arguments or [...arguments] or Array.prototype.slice.call(arguments) or [].slice.call(arguments) .

The math object

Some useful properties: PI , E , LN2 , LN10 , LOG2E , LOG10E etc.

A few useful functions are: abs , floor , ceil , sqrt , min , max , and random . There are trigonometric functions too.

// Generate random numbers between 0 and upperLimit function randomInFirst (upperLimit) {

return Math.floor(Math.random() * upperLimit);

} for (let i = 0; i < 100; i++) {

console.log(randomInFirst(100));

}



Math is a namespace for a bunched together mathematical thingies.

The global object

Okay, look, I am an experienced JS dev, so I can tell you that this book is very basic. For example, here it misses an opportunity to discuss global namespace in various environments. Browsers have window , node has global .

It also fails to warn you to not create global variables as it pollutes and is a bad practice.

It also fails to tell you that following function will end up creating a global variable x that can be accessed as window.x in browsers and as global.x in node env.

function globalPollutor () {

x = 10;

}

Summary

blech

Book again misses an opportunity to draw attention to very basic things about objects.

// Object

var gitfaf = { name: 'Git Faf', profession: 'all things JS' };

gitfaf is an object that has two properties: name and profession.

// Object of arrays

var skills = {

languages: [ 'c', 'javascript', 'c#' ],

tools: [ 'VS Code', 'vim', 'VS', 'ICE' ],

frameworks: [ '.NET', 'Node', 'AngularJS' ]

};

There are three arrays that the object skills contain; which can be accessed as skills.languages , skills.tools , skills.frameworks .

// Adding skills object to gitfaf object

gitfaf.skills = skills;

Now you can access languages as gitfaf.skills.languages .

Exercise — The sum of a range

function range (start, end) {

let out = [];

for (let i = start; i <= end; i++) {

out.push(i);

}

return out;

} function sum (array) {

return array.reduce((accumulator, current) => accumulator + current, 0);

} console.log(sum(range(1, 10))); // 55

Problem also asks for a step param version of range function and also that step can be negative. Lets do that.

function range (start, end) {

return steppedRange(start, end, 1);

} function steppedRange (start, end, step) {

step = step || 1; // this makes 1 as default step value.

let out = [];

if (step > 0) {

for (let i = start; i <= end; i += step) {

out.push(i);

}

} else {

for (let i = start; i >= end; i += step) {

out.push(i);

}

}

return out;

}

Exercise — Reversing an array

Exercise — A list

Iteratively Generated list

I didn’t write prepend() and nth() and also didn’t write recursive versions. These I’ll tackle later when I’d go through DS and Algorithms.

Exercise — Deep Equal