JavaScript:
Data Structures - Objects & Arrays
Lecturer: Иo1lz
OUTLINE
- Data Sets
- Objects
- Multability
- The Lycanthrope's Log
- Further Arrayology
-
Numbers, Booleans, and strings are the atoms that data structures are built from.
- Many types of information require more than one atom
- We'll introduce basic data structures.
Preface
The Weresquirrel
Every now and then, usually between 8 p.m. and 10 p.m., Jacques finds himself transforming into a small furry rodent with a bushy tail.
On one hand, Jacques is quite glad that he doesn't have classic lycanthropy. Turning into a squirrel does cause fewer problems than turning into a wolf. Instead of having to worry about accidentally eating the neighbor (that would be awkward), he worries about being eaten by the neighbor's cat. After two occasions where he woke up on a precariously thin branch in the crown of an oak, naked and disoriented, he has taken to locking the doors and windows of his room at night and putting a few walnuts on the floor to keep himself busy.
That takes care of the cat and tree problems. But Jacques would prefer to get rid of his condition entirely. The irregular occurrences of the transformation make him suspect that they might be triggered by something. For a while, he believed that it happened only on days when he had been near oak trees. But avoiding oak trees did not stop the problem.
Switching to a more scientific approach, Jacques has started keeping a daily log of everything he does on a given day and whether he changed form. With this data he hopes to narrow down the conditions that trigger the transformations.
Data Sets
To work with a chunk of digital data, we'll first have to find a way to represent it in our machine's memory.
e.g. to represent a collection of the numbers 2, 3, 5, 7, and 11, there are 2 ways:
- string
- array
let listOfNumbers = [2, 3, 5, 7, 11];
console.log(listOfNumbers[2]);
// -> 5
console.log(listOfNumbers[0]);
// -> 2
console.log(listOfNumbers[2 - 1]);
// -> 3
Properties
- Almost all JavaScript values have properties.
- The exception null and undefined.
null.length;
// -> TypeError: null has no properties
The two symbol to access properties:
- dot
- square bracket
value.x;
value[x];
The 3 ways to access properties:
objectName.property;
// person.age
objectName["property"];
// person["age"]
objectName[expression];
// x = "age"; person[x];
- The dot notation works only with names that look like valid binding string
- If you want to access a property named 2 or "Ore wa tensai desu", you must use square brackets:
- value[2]
- value["Ore wa tensai desu"]
Methods
Both string and array objects contain a number of properties that hold function values.
let doh = "Doh";
console.log(typeof doh.toUpperCase);
// -> function
console.log(doh.toUpperCase());
// -> DOH
Properties that contain functions are generally called methods of the value.
e.g. toUpperCase is a method of a string
let sequence = [1, 2, 3];
sequence.push(4);
sequence.push(5);
console.log(sequence);
// -> [1, 2, 3, 4, 5]
console.log(sequence.pop());
// -> 5
console.log(sequence);
// -> [1, 2, 3, 4]
Objects
- Back to the weresquirrel. A set of daily log entries can be represented as an array.
- Values of the type object are arbitrary collections of properties.
- to create an object is by using braces as an expression
let day1 = {
squirrel: false,
events: ["work", "touched tree", "pizza", "running"]
};
console.log(day1.squirrel);
// -> false
console.log(day1.wolf);
// -> undefined
day1.wolf = false;
console.log(day1.wolf);
// -> false
console.log(day1);
// -> Object{ squirrel: false, events: (4) [...], wolf: false }
- <propertyName>: <value>
- Properties whose names aren't valid binding names or valid numbers have to be quoted.
let descriptions = {
work: "Went to work",
"touched tree": "Touched a tree"
};
Braces have two meanings in JavaScript:
- at the start of a statement
- they start a block of statements
- in any other position, they describe an object
It's possible to assign a value to a property expression with the "=" operator.
- replace the property's value if existed
- create a new property
let anObject = {
left: 1,
right: 2
};
console.log(anObject.left);
// -> 1
delete anObject.left;
console.log(anObject.left);
// -> undefined
console.log("left" in anObject);
// -> false
console.log("right" in anObject);
// -> true
console.log(Object.keys({x: 0, y: 0, z: 2}));
// -> ["x", "y", "z"]
let objectA = {a: 1, b: 2};
Object.assign(objectA, {b: 3, c: 4});
console.log(objectA);
// -> {a: 1, b: 3, c: 4}
console.log(typeof []);
// -> object
Multability
We saw that object values can be modified. The types of values, such as numbers, strings, and Booleans, are all immutable
It is impossible to change values of those types
Objects work differently.
You can change their properties, causing a single object value to have different content at different times.
let object1 = {value: 10};
let object2 = object1;
let object3 = {value: 10};
console.log(object1 == object2);
// -> true
console.log(object1 == object3);
// -> false
object1.value = 15;
console.log(object2.value);
// -> 15
console.log(object3.value);
// -> 10
const score = {visitors: 0, home: 0}; // This is fine.
score.visitors = 1; // This is not allowed.
score = {visitors: 1, home: 1};
The Lycanthrope's Log
let journal = [];
function addEntry(events, squirrel){
journal.push({events, squirrel});
}
addEntry(["work", "touched tree", "pizza", "running", "television"], false);
addEntry(["work", "ice cream", "cauliflower", "lasagna", "touched tree", "brushed teeth"], false);
addEntry(["weekend", "cycling", "break", "peanuts", "beer"], true);
!pizza | pizza | |
---|---|---|
!squirrel | 76 | 9 |
squirrel | 4 | 1 |
Computing Correlation
To represent a two-by-two table in JavaScript:
- four-element array => ([76, 9, 4, 1])
- two-element binary array => ([76, 9], [4, 1])
- Object with property names like "11"
We'll interpret the indices to the array as two-bit binary numbers
function phi(table){
return (table[3] * table[0] - table[2] * table[1]) / Math.sqrt((table[2] + table[3]) * (table[0] + table[1]) * (table[1] + table[3]) * (table[0] + table[2]));
}
console.log(phi([76, 9, 4, 1]));
// -> 0.068599434
function tableFor(event, journal){
let table = [0, 0, 0, 0];
for(let i = 0;i < journal.length;i++){
let entry = journal[i], index = 0;
if(entry.events.includes(event)) index += 1;
if(entry.squirrel) index += 2;
table[index] += 1;
}
return table
}
console.log(tableFor("pizza", JOURNAL));
// -> [76, 9, 4, 1]
Array Loops
for(let i = 0;i < journal.length;i++){
let entry = journal[i];
// Do something with entry
}
for(let entry of journal){
console.log(`${entry.events.length} events.`);
}
The Final Analysis
function journalEvents(journal){
let events = [];
for(let entry of journal){
for(let event of entry.events){
if(!events.includes(event)){
events.push(event);
}
}
}
return events;
}
console.log(journalEvents(JOURNAL));
// -> ["carrot", "exercise", ...]
for(let event of journalEvents(JOURNAL)){
console.log(event + ":", phi(tableFor(event, JOURNAL)));
}
for(let event of journalEvents(JOURNAL)){
let correlation = phi(tableFor(event, JOURNAL));
if(correlation > 0.1 || correlation < -0.1){
console.log(event + ":", correlation);
}
}
for(let entry of JOURNAL){
if(entry.events.includes("peanuts") && !entry.events.includes("brushed teeth")){
entry.events.push("peanut teeth");
}
}
console.log(phi(tableFor("peanut teeth", JOURNAL)));
// -> 1
That's a strong result. The phenomenon occurs precisely when Jacques eats peanuts and fails to brush his teeth. If only he weren't such a slob about dental hygiene, he'd have never even noticed his affliction.
Knowing this, Jacques stops eating peanuts altogether and finds that his transformations don't come back.
For a few years, things go great for Jacques. But at some point he loses his job. Because he lives in a nasty country where having no job means having no medical services, he is forced to take employment with a circus where he performs as The Incredible Squirrelman , stuffing his mouth with peanut butterbefore every show.
One day, fed up with this pitiful existence, Jacques fails to change back into his human form, hops through a crack in the circus tent, and vanishes into the forest. He is never seen again.
Further Arrayology
let todoList = [];
function remember(task){
todoList.push(task);
}
function getTask(){
return todoList.shift();
}
function rememberUrgently(task){
todoList.unshift(task);
}
unshift、shift
console.log([1, 2, 3, 2, 1].indexOf(2));
// -> 1
console.log([1, 2, 3, 2, 1].lastIndexOf(2));
// -> 3
indexOf、lastIndexOf
console.log([0, 1, 2, 3, 4].slice(2, 4))
// -> [2, 3]
console.log([0, 1, 2, 3, 4].slice(2))
// -> [2, 3, 4]
slice
console.log([0, 1, 2, 3, 4].slice(2, 4))
// -> [2, 3]
console.log([0, 1, 2, 3, 4].slice(2))
// -> [2, 3, 4]
slice
function remove(array, index){
return array.slice(0, index).concat(array.slice(index + 1));
}
console.log(remove(["a", "b", "c", "d", "e"], 2));
// -> ["a", "b", "d", "e"]
concat
Strings and Their Properties
let kim = "Kim";
kim.age = 88;
console.log(kim.age);
// -> undefined
console.log("coconuts".slice(4, 7));
// -> nut
console.log("coconuts".indexOf("u"));
// -> 5
slice、indexOf
console.log("one two three".indexOf("ee"));
// -> 11
console.log(" okay \n".trim());
// -> okay
trim
console.log(String(6).padStart(3, "0"));
// -> 006
padStart
let sentence = "Secretarybirds specialize in stomping";
let words = sentence.split(" ");
console.log(words);
// -> ["Secretarybirds", "specialize", "in", "stomping"]
console.log(words.join(". "));
// -> Secretarybirds. specialize. in. stomping
split、join
console.log("LA".repeat(3));
// -> LALALA
repeat
length
let string = "abc";
console.log(string.length);
// -> 3
console.log(string[1]);
// -> b
Rest Parameters
function max(...numbers){
let result = -Infinity;
for(let number of numbers){
if(number > result) result = number;
}
return result;
}
console.log(max(4, 1, 9, -2));
// -> 9
let numbers = [5, 1, 7];
console.log(max(...numbers));
// -> 7
let words = ["never", "fully"];
console.log(["will", ...words, "understand"]);
// -> ["will", "never", "fully", "understand"]
The Math Object
function randomPointOnCircle(radius){
let angle = Math.random() * 2 * Math.PI;
return {
x: radius * Math.cos(angle),
y: radius * Math.sin(angle)
};
}
console.log(randomPointOnCircle(2));
// -> {x: 0.3667, y: 1.966}
console.log(Math.random());
console.log(Math.random());
console.log(Math.random());
Math.random
console.log(Math.floor(Math.random() * 10));
Math.floor
- Math.ceil
- Math.round
- Math.abs
Destructuring
function phi(table){
return (table[3] * table[0] - table[2] * table[1]) / Math.sqrt((table[2] + table[3]) * (table[0] + table[1]) * (table[1] + table[3]) * (table[0] + table[2]));
}
2 ways to simplization:
- define "let n00 = table[0] ...
- A succinct way to do this
function phi([n00, n01, n10, n11]){
return (n11 * n00 - n10 * n01) / Math.sqrt((n10 + n11) * (n00 + n01) * (n01 + n11) * (n00 + n10));
}
Thanks for listening.
JavaScript: Data Structures-Objects & Arrays
By Иo1lz
JavaScript: Data Structures-Objects & Arrays
This is the slide that refer from "Eloquent JavaScript" chapter 4.
- 145