SitePoint Sponsor

User Tag List

Results 1 to 17 of 17
  1. #1
    Unobtrusively zen silver trophybronze trophy
    paul_wilkins's Avatar
    Join Date
    Jan 2007
    Location
    Christchurch, New Zealand
    Posts
    14,702
    Mentioned
    101 Post(s)
    Tagged
    4 Thread(s)

    This Week in JavaScript - 14 October 2013

    This is a weekly update of some interesting things relating to JavaScript, to help encourage discussion and to bring some potentially new ideas to the fore.

    Here's what we've seen of interest this week.

    Techniques

    Making a Simple Game in JavaScript Step-By-Step - a video talk that takes you through the basics of creating a game

    Searching using Array.prototype.reduce - with last weeks JavaScript under pressure, this reduce function became quite handy

    Libraries

    Lightweight URL argument and parameter parser - retrieve querystring and hash tag information with ease

    FullCalendar - an open source event calendar from MIT with drag & drop, and is compatible with google calendar

    Advanced

    Currying in Javascript - do you need to handle functions that can be only partially evaluated?

    Maintainable Automated UI Tests - removing brittleness from difficult to maintain UI tests

    Frameworks

    jsdb.io - definitive source of the best JavaScript frameworks, plugins, and tools

    Getting MEAN - A boilerplate Mongo, Express, Angular, and Node stack for appllication development

    The lighter side

    Full Screen Mario


    Take a look at these recent happenings in JavaScript, let us know what you think about them, and we'll have some more to inspire you next week.

    Feel free to PM me or PM Pullo if you have anything interesting for the next issue.
    Programming Group Advisor
    Reference: JavaScript, Quirksmode Validate: HTML Validation, JSLint
    Car is to Carpet as Java is to JavaScript

  2. #2
    It's all Geek to me silver trophybronze trophy
    ralph.m's Avatar
    Join Date
    Mar 2009
    Location
    Melbourne, AU
    Posts
    24,176
    Mentioned
    454 Post(s)
    Tagged
    8 Thread(s)
    Quote Originally Posted by paul_wilkins View Post
    The lighter side
    Hehe, that game is hilarious.

  3. #3
    Non-Member
    Join Date
    Feb 2012
    Posts
    892
    Mentioned
    10 Post(s)
    Tagged
    0 Thread(s)
    For a better understanding of functional programming patterns, it should be mentioned that the solution for javascript under pressure #4 requires a filter not a reduce, or a fold how it is also called.

    A filter will permit to return all the values that satisfy a certain criteria, while reduce is used to build up a final value. I've contacted UsVsTh3m on the matter and they've actually confirmed the test cases are lacking:

    That's true; I deliberately didn't include that test case because it seemed a bit too much to ask of novice programmers.

  4. #4
    Gre aus'm Pott gold trophysilver trophybronze trophy
    Pullo's Avatar
    Join Date
    Jun 2007
    Location
    Germany
    Posts
    5,938
    Mentioned
    214 Post(s)
    Tagged
    12 Thread(s)
    Quote Originally Posted by ralph.m View Post
    Hehe, that game is hilarious.
    Second that. I've just wasted an hour remembering what fun Mario used to be.

  5. #5
    Gre aus'm Pott gold trophysilver trophybronze trophy
    Pullo's Avatar
    Join Date
    Jun 2007
    Location
    Germany
    Posts
    5,938
    Mentioned
    214 Post(s)
    Tagged
    12 Thread(s)
    So I'm reading the article Searching using Array.prototype.reduce and I've run into a little challenge that the author has set.

    Code JavaScript:
    entries = Array.apply(0, Array(entries.length)).map(function () {
      return entries.splice(findLongest(entries).index, 1).pop();
    });

    Quote Originally Posted by article author
    See if you can figure out the reason behind the use of splice and pop there.
    To give a little more context, my code looks like this:

    Code JavaScript:
    var strings = ["aa", "b", "cccc", "ddd"];
     
    function findLongest(entries) {
      return entries.reduce(function (longest, entry, index) {
        return entry.length > longest.value.length ?
          { index: index, value: entry } : longest;
      }, { index: -1, value: '' });
    }
     
    var sortedStrings = Array.apply(0, Array(strings.length)).map(function () {
      return strings.splice(findLongest(strings).index, 1).pop();
    });
     
    console.log(sortedStrings);

    Would it be correct to say that in the above code (my version), the following is true:

    In the callback function passed to .map(), we are removing the longest element from the strings array (using splice) and inserting it it into the corresponding element of the sortedStrings array.
    We need to call .pop() as splice returns an array containing the removed elements.

    Is there any reason for the use of .splice() or .pop() that I have missed?

  6. #6
    Non-Member
    Join Date
    Feb 2012
    Posts
    892
    Mentioned
    10 Post(s)
    Tagged
    0 Thread(s)
    I take many issues with what Ariya Hidayat writes. I've only read two of its posts, but it looks inadvisable. But later about this.

    The "secret" is not with splice or pop, the "secret" is with Array.apply(0, Array(strings.length)). With that, he's trying to build ahead an array with an exact number of "blank" elements in it: the length of strings. Then, he uses split and pop to "fill in the blanks".


    Now back to my issues. He's oblivious to many things and misinformed on many others. The technique he describes for creating an array with a known number of "blank" elements without using a loop belongs to another post of his: http://ariya.ofilabs.com/2013/07/seq...ipt-array.html, where he tries to convince me that Array(3) doesn't produce [undefined, undefined, undefined] but... holes:
    Code:
    Array(3);                  // [,,,]
    Array.apply(0, Array(3));  // [undefined, undefined, undefined]
    The whole premise is wrong, in Javascript anything undeclared is undefined. He's confusing array display (C's printf analogy) with actual array values. Anecdotally, there are three commas for Array(3) representation, which suggest a return array of length 4, not 3.

    The programming style is wrong in many ways: not caching variables in the for statement, not caching object properties he uses, obscure and unclear "apply"cations and so on, all in the name of a functional programming design he clearly doesn't control.

    You can take this as a vent, but it's not. The guy just needs some more self time before posting functional programming Javascript blog posts.

    Anyway, I should also post some code. It's only fair that I expose myself to the same criticism I render. For a reduce only solution that returns: the longest length, longest strings and their respective indeces

    Code:
    var test = ["a", 0, "aa", 1, "two", 3,  "zero", "one", "four", "five", 6],
        longestStrings = [];
    
    
    var returnValue = test.reduce(
        function(initialValue, currentValue, index){
    
            var max           = initialValue,
                currentLength = currentValue.length;
    
            if (currentLength >= max) {
    
                if (currentLength > max) {
                    max = currentLength;
                    longestStrings.length = 0;
                };
    
                longestStrings.push({"string": currentValue, "index": index});
            };
                
            return max;
        }
    , 0);
    
    console.log("max length: ", returnValue);
    console.log("longest elements: ", longestStrings);

  7. #7
    Non-Member
    Join Date
    Feb 2012
    Posts
    892
    Mentioned
    10 Post(s)
    Tagged
    0 Thread(s)
    But, like I said, from a functional programming pattern point of view, the solution to the longest strings, and I repeat this, strings, not string, is a filter.

    A reduce has its place here. It will be used to build up a final value: maximum string length. Then, a filter based on this maximum length is applied to the initial array. These are the expected uses for reduce and filter. Of course, one can jump the gun and solve the problem with just reduce, or take any other path and code randomly, but while it may solve the problem, those patterns will never come close to making sense to a functional programmer.

    Anyway, here's my approach:
    Code:
    function maxLength(initialValue, currentValue){
        var max           = initialValue,
            currentLength = currentValue.length;
    
            if (currentLength > max) {
                max = currentLength;
            };
            
        return max;
    };
    
    function hasMaxLength(element, index, array) {
        var condition = false, 
            max       = array.reduce(maxLength, 0);
    
        if (element.length >= max) {
            condition = true;
        };
    
        return condition;
    };
    
    console.log(
        ["a", 0, "aa", 1, "two", 3,  "zero", "one", "four", "five", 6]
        .filter(hasMaxLength)
    );
    What's left here TODO is making it work with nested array values inside the array (and perhaps some caching for the max value). This would require a "flatten" approach before "reduce" and "filter". A "flatten" solution is actually simple to implement, if there's demand I guess I could build a more comprehensive longest strings module. These are just some rushed up solutions.

    ERATA: In the post above I've written that anything undeclared is undefined. I meant anything not initialized is undefined.

  8. #8
    Gre aus'm Pott gold trophysilver trophybronze trophy
    Pullo's Avatar
    Join Date
    Jun 2007
    Location
    Germany
    Posts
    5,938
    Mentioned
    214 Post(s)
    Tagged
    12 Thread(s)
    Thanks for the response myty. Very interesting!
    I'm a bit busy tomorrow, but I'll read what you wrote in more depth and reply back here soon.

  9. #9
    Gre aus'm Pott gold trophysilver trophybronze trophy
    Pullo's Avatar
    Join Date
    Jun 2007
    Location
    Germany
    Posts
    5,938
    Mentioned
    214 Post(s)
    Tagged
    12 Thread(s)
    Hi myty,

    So, now I have had a bit of time to look at what you posted and work through your code.

    I've taken on board everything you wrote in post#6, although I don't think the author is seriously suggesting we go around writing things like Array.apply(0, Array(3));, rather just playing around with what's possible.

    As regards your code in post#7, I agree it is better to account for multiple longest strings.
    However, in your solution you are invoking the maxLength callback 121 times (11 * 11).
    Wouldn't some kind of caching be appropriate here? How might one implement that?
    AFAIK there is no array.flatten method in JS.

    Also, you mention a functional programming approach several times in this post and various other posts.
    Could you recommend anywhere where I could find a good definition of functional programming and what the main advantages/disadvantages of this approach are?
    Admittedly this is something that I could Google, but if you have a recommendation I would prefer that.

  10. #10
    Non-Member
    Join Date
    Feb 2012
    Posts
    892
    Mentioned
    10 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Pullo View Post
    Also, you mention a functional programming approach several times in this post and various other posts.
    Could you recommend anywhere where I could find a good definition of functional programming and what the main advantages/disadvantages of this approach are?
    This is a good place to start: http://learnyouahaskell.com/introduc...-whats-haskell. Read at least 'till http://learnyouahaskell.com/higher-order-functions.

    I'll get back to you with the rest.

  11. #11
    Programming Since 1978 silver trophybronze trophy felgall's Avatar
    Join Date
    Sep 2005
    Location
    Sydney, NSW, Australia
    Posts
    16,810
    Mentioned
    25 Post(s)
    Tagged
    1 Thread(s)
    Quote Originally Posted by Pullo View Post
    However, in your solution you are invoking the maxLength callback 121 times (11 * 11).
    Wouldn't some kind of caching be appropriate here? How might one implement that?

    Code:
    Function.prototype.memoize = function() {
       var self, cache;
       self = this;
       cache = {};
       return function () {
          var args, entry, i, cArg;  
          args = Array.prototype.slice.call(arguments);  
          entry = '';  
          cArg = null; 
          i = args.length;
          while(i--) {
             cArg = args[i];  
             entry += (cArg === Object(cArg)) ? JSON.stringify(cArg) : cArg;  
           } 
          return (entry in cache) ? cache[entry] : cache[entry] = self.apply(self, args);  
       };  
    }
    Then add:

    Code:
    hasMaxLength = hasMaxLength.memoize();
    after defining the hasMaxLength function.

    Then any subsequent calls to hasMaxLength with the same parameters as in a prior call will just return the same results as that prior call directly from the cache.
    Stephen J Chapman

    javascriptexample.net, Book Reviews, follow me on Twitter
    HTML Help, CSS Help, JavaScript Help, PHP/mySQL Help, blog
    <input name="html5" type="text" required pattern="^$">

  12. #12
    Non-Member
    Join Date
    Feb 2012
    Posts
    892
    Mentioned
    10 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Pullo View Post
    As regards your code in post#7, I agree it is better to account for multiple longest strings.
    However, in your solution you are invoking the maxLength callback 121 times (11 * 11).
    Wouldn't some kind of caching be appropriate here? How might one implement that?
    @Pullo ;

    Hi there.

    One way of doing it is to pass it to the filter function callback. There is the possibility to pass an object to the callback, which can then be referred to as this. We simply build this object using the object literal syntax and pass it. It has only one entry: max. Then we simply call this.max inside the callback.

    Code:
    function maxLength(initialValue, currentValue){
        var max           = initialValue,
            currentLength = currentValue.length;
    
            if (currentLength > max) {
                max = currentLength;
            };
            
        return max;
    };
    
    function hasMaxLength(element, index) {
        var condition = false;
    
        if (element.length >= this.max) {
            condition = true;
        };
    
        return condition;
    };
    
    myArr = ["a", 0, "aa", 1, "two", 3,  "zero", "one", "four", "five", 6];
    console.log(myArr.filter(hasMaxLength, { max: myArr.reduce(maxLength, 0) }));

    Quote Originally Posted by Pullo View Post
    AFAIK there is no array.flatten method in JS.
    We need to build it, but it's not that hard. I'll put something together later.

  13. #13
    Non-Member
    Join Date
    Feb 2012
    Posts
    892
    Mentioned
    10 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Pullo View Post
    Also, you mention a functional programming approach several times in this post and various other posts.
    Could you recommend anywhere where I could find a good definition of functional programming and what the main advantages/disadvantages of this approach are?.
    I found this, a more recent article from an author I personally appreciate: http://tech.pro/tutorial/1611/functional-javascript
    You can also check out his free ebook: JavaScript Succinctly.

  14. #14
    Gre aus'm Pott gold trophysilver trophybronze trophy
    Pullo's Avatar
    Join Date
    Jun 2007
    Location
    Germany
    Posts
    5,938
    Mentioned
    214 Post(s)
    Tagged
    12 Thread(s)
    Quote Originally Posted by myty View Post
    Quote Originally Posted by myty View Post
    I found this, a more recent article from an author I personally appreciate: http://tech.pro/tutorial/1611/functional-javascript
    You can also check out his free ebook: JavaScript Succinctly.
    Thank you. I'm off on vacation for a couple of weeks, so this'll make for some good reading material.
    I'm also reading the first chapter of Functional Programming in Scala, which seems quite promising.

  15. #15
    Gre aus'm Pott gold trophysilver trophybronze trophy
    Pullo's Avatar
    Join Date
    Jun 2007
    Location
    Germany
    Posts
    5,938
    Mentioned
    214 Post(s)
    Tagged
    12 Thread(s)
    Hi felgall,

    Quote Originally Posted by felgall View Post
    Code:
    Function.prototype.memoize = function() {
       var self, cache;
       self = this;
       cache = {};
       return function () {
          var args, entry, i, cArg;  
          args = Array.prototype.slice.call(arguments);  
          entry = '';  
          cArg = null; 
          i = args.length;
          while(i--) {
             cArg = args[i];  
             entry += (cArg === Object(cArg)) ? JSON.stringify(cArg) : cArg;  
           } 
          return (entry in cache) ? cache[entry] : cache[entry] = self.apply(self, args);  
       };  
    }
    Then add:

    Code:
    hasMaxLength = hasMaxLength.memoize();
    after defining the hasMaxLength function.

    Then any subsequent calls to hasMaxLength with the same parameters as in a prior call will just return the same results as that prior call directly from the cache.
    I was having a bit of a discussion with myty lately regarding memoization, so was quite annoyed with myself that I didn't at least hit upon this method as a possible method of caching the results.

    Thank you!

  16. #16
    Gre aus'm Pott gold trophysilver trophybronze trophy
    Pullo's Avatar
    Join Date
    Jun 2007
    Location
    Germany
    Posts
    5,938
    Mentioned
    214 Post(s)
    Tagged
    12 Thread(s)
    Quote Originally Posted by myty View Post
    One way of doing it is to pass it to the filter function callback. There is the possibility to pass an object to the callback, which can then be referred to as this.
    That's neat and simple! Thanks.
    Had I had to do this for real, I think I would have got there in the end, but my solution would have been (much) more complex than necessary.
    I'm hoping that by learning a little more about programming styles, I will be better equipped to choose the right tools for the job.

  17. #17
    Non-Member
    Join Date
    Feb 2012
    Posts
    892
    Mentioned
    10 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Pullo View Post
    I'm hoping that by learning a little more about programming styles, I will be better equipped to choose the right tools for the job.
    Me and you both. Enjoy your vacation.


Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •