Data Structures - Objects & Arrays
Lecturer: Иo1lz
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.
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:
let listOfNumbers = [2, 3, 5, 7, 11];
console.log(listOfNumbers[2]);
// -> 5
console.log(listOfNumbers[0]);
// -> 2
console.log(listOfNumbers[2 - 1]);
// -> 3
null.length;
// -> TypeError: null has no properties
The two symbol to access properties:
value.x;
value[x];
The 3 ways to access properties:
objectName.property;
// person.age
objectName["property"];
// person["age"]
objectName[expression];
// x = "age"; person[x];
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]
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 }
let descriptions = {
work: "Went to work",
"touched tree": "Touched a tree"
};
Braces have two meanings in JavaScript:
It's possible to assign a value to a property expression with the "=" operator.
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
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};
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 |
To represent a two-by-two table in JavaScript:
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]
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.`);
}
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.
let todoList = [];
function remember(task){
todoList.push(task);
}
function getTask(){
return todoList.shift();
}
function rememberUrgently(task){
todoList.unshift(task);
}
console.log([1, 2, 3, 2, 1].indexOf(2));
// -> 1
console.log([1, 2, 3, 2, 1].lastIndexOf(2));
// -> 3
console.log([0, 1, 2, 3, 4].slice(2, 4))
// -> [2, 3]
console.log([0, 1, 2, 3, 4].slice(2))
// -> [2, 3, 4]
console.log([0, 1, 2, 3, 4].slice(2, 4))
// -> [2, 3]
console.log([0, 1, 2, 3, 4].slice(2))
// -> [2, 3, 4]
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"]
let kim = "Kim";
kim.age = 88;
console.log(kim.age);
// -> undefined
console.log("coconuts".slice(4, 7));
// -> nut
console.log("coconuts".indexOf("u"));
// -> 5
console.log("one two three".indexOf("ee"));
// -> 11
console.log(" okay \n".trim());
// -> okay
console.log(String(6).padStart(3, "0"));
// -> 006
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
console.log("LA".repeat(3));
// -> LALALA
let string = "abc";
console.log(string.length);
// -> 3
console.log(string[1]);
// -> b
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"]
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());
console.log(Math.floor(Math.random() * 10));
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:
function phi([n00, n01, n10, n11]){
return (n11 * n00 - n10 * n01) / Math.sqrt((n10 + n11) * (n00 + n01) * (n01 + n11) * (n00 + n10));
}