Skip to main content

Ivan Teoh

Something personal yet public

Javascript: 101 Week 2 Track 2

For track 2 on week 2, I basically need to read chapter 4 and 5 on Eloquent JavaScript.

Reflection

  • It is tough to explain Objects and Arrays to my grandmother.
  • If I would pick either bad code or a naughty browser for my best practice for errors, I would be bad code.

Homework

  • Ex. 4.1: The solution for the cat problem talks about a 'set' of names. A set is a collection of values in which no value may occur more than once. If names are strings, can you think of a way to use an object to represent a set of names? Show how a name can be added to this set, how one can be removed, and how you can check whether a name occurs in it.

    167-exercise41.js (Source)

    var cat = {}; // a 'set' of names
    cat['Red Lion'] = {'colour': 'grey', 'size': 46}; // a name is added to this set
    cat['Doctor Hobbles'] = {'colour': 'white', 'size': 15};
    cat['Little Iroquois'] = {'colour': 'yellow', 'size': 30};
    delete cat['Doctor Hobbles']; // a name is removed from this set
    if ('Red Lion' in cat) { // check whether a name occurs in this set.
        alert('you have "Red Lion" cat.');
    }
    
  • Ex. 4.2: Write a function range that takes one argument, a positive number, and returns an array containing all numbers from 0 up to and including the given number. An empty array can be created by simply typing []. Also remember that adding properties to an object, and thus also to an array, can be done by assigning them a value with the = operator. The length property is automatically updated when elements are added.

    167-exercise42.js (Source)

    function range(num) {
        var list = [];
        for (var i = 0; i <= num; i++) {
            list[i] = i;
        }
        return list;
    }
    document.write(range(5));
    
  • Ex. 4.3: split and join are not precisely each other's inverse. string.split(x).join(x) always produces the original value, but array.join(x).split(x) does not. Can you give an example of an array where .join(" ").split(" ") produces a different value?

    167-exercise43.js (Source)

    var sentence = ["We are", "family"];
    sentence.join(" ").split(" ");
    
  • Ex. 4.4: Write a function called startsWith that takes two arguments, both strings. It returns true when the first argument starts with the characters in the second argument, and false otherwise.

    167-exercise44.js (Source)

    function startsWith (firstString, secondString) {
        var result = false;
        firstLength = firstString.length;
        secondLength = secondString.length;
        if (secondLength > firstLength)
            return result;
    
        if (firstString.slice(0, secondLength) == secondString)
            result = true;
        return result;
    }
    document.write(startsWith("oranges", "orange")); // true
    document.write(startsWith("peach", "orange"));   // false
    document.write(startsWith("peaches", "grape"));  // false
    
  • Ex. 4.5: Can you write a function catNames that takes a paragraph as an argument and returns an array of names? Strings have an indexOf method that can be used to find the (first) position of a character or sub-string within that string. Also, when slice is given only one argument, it will return the part of the string from the given position all the way to the end. It can be helpful to use the console to 'explore' functions. For example, type "foo: bar".indexOf(":") and see what you get.

    167-exercise45.js (Source)

    function catNames(paragraph) {
        var result = [];
        var colon = paragraph.indexOf(":");
        allCat = paragraph.slice(colon + 1);
        names = allCat.split(",");
        for (var i = 0; i < names.length; i++) {
            var catName = names[i].split("");
            var startName;
            var endName;
            // Trims whitespace from the left side of the string.
            for (var j = 0; j < catName.length; j++) {
                startName = j;
                if (catName[j] != " ")
                    break;
            }
            // Trims whitespace from the right side of the string.
            for (var k = catName.length - 1; k > -1; k--) {
                endName = k;
                if (catName[k] != " ")
                    break;
            }
            result.push(names[i].slice(startName, endName+1));
        }
        return result;
    }
    var paragraph = "born 05/04/2006 (mother Lady Penelope): Red Lion, Doctor" +
      "Hobbles the 3rd, Little Iroquois";
    document.write(catNames(paragraph));
    
  • Ex. 4.6: The date part, "died 27/04/2006: Black Leclère", is always in the exact same place of a paragraph. How convenient. Write a function extractDate that takes such a paragraph as its argument, extracts the date, and returns it as a date object.

    167-exercise46.js (Source)

    function extractDate(paragraph) {
        var colon = paragraph.indexOf(":");
        var space = paragraph.indexOf(" ");
        var allDate = paragraph.slice(space + 1, colon);
        var dates = allDate.split("/");
        var day = dates[0];
        var month = dates[1];
        var year = dates[2];
        var result = new Date(year, month-1, day);
        return result;
    }
    var paragraph = "died 27/04/2006: Black Leclère";
    document.write(extractDate(paragraph));
    
  • Ex. 4.7: The thing that extractMother does can be expressed in a more general way. Write a function between that takes three arguments, all of which are strings. It will return the part of the first argument that occurs between the patterns given by the second and the third arguments. So between("born 15/11/2003 (mother Spot): White Fang", "(mother ", ")") gives "Spot". between("bu ] boo [ bah ] gzz", "[ ", " ]") returns "bah". To make that second test work, it can be useful to know that indexOf can be given a second, optional parameter that specifies at which point it should start searching.

    167-exercise47.js (Source)

    function between(paragraph, firstPattern, secondPattern) {
        var start = paragraph.indexOf(firstPattern) + firstPattern.length;
        var end = paragraph.indexOf(secondPattern, start);
        return paragraph.slice(start, end);
    }
    document.write(between("born 15/11/2003 (mother Spot): White Fang",
      "(mother ", ")")); // "Spot"
    document.write(between("bu ] boo [ bah ] gzz", "[ ", " ]")); // "bah"
    
  • Ex. 4.8: The formatDate function used by catInfo does not add a zero before the month and the day part when these are only one digit long. Write a new version that does this.

    167-exercise48.js (Source)

    function formatDate(date) {
        var month = date.getMonth() + 1;
        var day = date.getDate();
      return ((day < 10)? ("0" + day) : day) +
             "/" + ((month < 10)? ("0" + month) : month) +
             "/" + date.getFullYear();
    }
    
    document.write(formatDate(new Date(2010, 11, 25))); // "25/12/2010"
    document.write(formatDate(new Date(2011, 1, 4))); // "04/02/2011"
    
  • Ex. 4.9: Write a function oldestCat which, given an object containing cats as its argument, returns the name of the oldest living cat.

    167-exercise49.js (Source)

    function oldestCat(cats) {
        var cat;
        var oldest;
        for (var name in cats) {
            if (!("death" in cats[name]) && !oldest || (oldest > cats[name].birth))
            {
                oldest = cats[name].birth;
                cat = cats[name].name;
            }
        }
      return cat;
    }
    var cats = {"Spot": {name:"Spot", birth: new Date(1997, 2, 5),
                mother: "Yellow"},
                "White": {name:"White", birth: new Date(1998, 7, 4),
                mother: "Zebra"},
                "Grey": {name:"Grey", birth: new Date(1996, 6, 3),
                mother: "Kitten"}};
    document.write(oldestCat(cats)); // "Grey"
    
  • Ex. 4.10: Extend the range function from exercise 4.2 to take a second, optional argument. If only one argument is given, it behaves as earlier and produces a range from 0 to the given number. If two arguments are given, the first indicates the start of the range, the second the end.

    167-exercise410.js (Source)

    function range(num, start) {
        var list = [];
        if (arguments.length < 2) {
            for (var i = 0; i <= num; i++) {
                list[i] = i;
            }
        } else {
            for (var x = 0, y = num; y <= start; x++, y++) {
                list[x] = y;
            }
        }
        return list;
    }
    document.write(range(5)); // 0, 1, 2, 3, 4, 5
    document.write(range(2, 5)); // 2, 3, 4, 5
    
  • Ex. 4.11: You may remember this line of code from the introduction: print(sum(range(1, 10))); We have range now. All we need to make this line work is a sum function. This function takes an array of numbers, and returns their sum. Write it, it should be easy.

    167-exercise411.js (Source)

    function range(num, start) {
        var list = [];
        if (arguments.length < 2) {
            for (var i = 0; i <= num; i++) {
                list[i] = i;
            }
        } else {
            for (var x = 0, y = num; y <= start; x++, y++) {
                list[x] = y;
            }
        }
        return list;
    }
    function sum(numbers) {
        result = 0;
        for (var i = 0; i < numbers.length; i++) {
            result += numbers[i];
        }
        return result;
    }
    document.write(sum(range(1, 10))); // 55
    

Comments

Comments powered by Disqus