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
φ = {n_{11}n_{00} - n_{10}n_{01} \over \sqrt{n_{1x} * n_{0x} * n_{x1} * n_{x0}}}

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