Hello and welcome to our community! Is this your first visit?
Register
Enjoy an ad free experience by logging in. Not a member yet? Register.
Results 1 to 1 of 1
  1. #1
    Regular Coder
    Join Date
    Sep 2010
    Location
    Far far away
    Posts
    122
    Thanks
    0
    Thanked 16 Times in 16 Posts

    Enumerate - Class for walking over collections in JScript

    Hi dear colleagues,
    I am using this feature the long time but I'd like to discuss some syntax sugar in the terms of differences of VBScript and JScript.


    Instead VBScript, JScript has no simple features to walk over collections. To solve this issue inventors from Redmond implemented Enumerator object

    The Enumerator object provides a way to access any member of a collection and behaves similarly to the For...Each statement in VBScript.
    But Enumerator hasn't laconism such as the For Each statement. There are excess of additional variables and bulky construction:

    Shorten example from the documentation
    Code:
    var fso = new ActiveXObject("Scripting.FileSystemObject");
    
    for (var e = new Enumerator(fso.Drives); ! e.atEnd(); e.moveNext()) {
        var drive = e.item();
        ...
    }
    The same code in VBScript
    Code:
    Set fso = CreateObject("Scripting.FileSystemObject")
    
    For Each drive In fso.Drives
        ...
    Next
    I suggest the little bit laconic construction, that i have called above as syntax sugar, completely implemented in the spirit of JavaScript. There is Enumerate object. It is unique namespace for three static method allowing to walk over collections, create an array or create an object based on a collection. Internally all these methods use the native object Enumerator, but the implementation is hidden within methods, the actual context is clear from additional variables, and the laconism is kept. Consider the following code in the comparison with the previous ones:

    Code:
    var fso = new ActiveXObject("Scripting.FileSystemObject");
    
    Enumerate.forItems(fso.Drives, function(drive)
        ...
    })
    Enumerate.forItems is invoked with two arguments:
    -- a collection, whose items should be walked up;
    -- a function that will be called for each item of a collection. It is invoked with two arguments -- the current item and a holder-collection. It the most of cases it is enough to point the first arguments. .

    This method does not return results.

    Enumerate.toArray transfers a collection and returns an array.
    Enumerate.toObject transfers a collection and returns an object.

    These method are exceeded because their functionality totally can be implemented by Enumerate.forItems. But they can be useful due to intuitive clarity in the context.

    Code:
    // Transfer a collection of unnamed arguments from a command line to an array
    // Each argument is available by it's index. For example unnamed[0] is the first item
    var unnamed = Enumerate.toArray(WScript.Arguments.Unnamed, function(value)
    {
        return value;
    });
    
    // Transfer a collection of named arguments from a command line
    // Arguments looks like /key[:value] will be transfered into an object like {"key": "value"}
    // "value" is available as named["key"]
    var named = Enumerate.toObject(WScript.Arguments.Named, function(key, collection)
    {
        return {
            key: key, 
            value: collection.item(key)
        };
    });
    Below is source of the Enumerate object. The full and actual version is available by the link http://code.google.com/p/jsxt/source.../Enumerator.js

    Code:
    var Enumerate = {};
    
    Enumerate.toArray = function(collection, fun, thisp)
    {
        if ( typeof fun != "function" ) {
            throw new TypeError();
        }
    
        var result = [];
    
        var fc = new Enumerator(collection);
        for ( ; ! fc.atEnd(); fc.moveNext()) {
            var i = fc.item();
            result.push(fun.call(thisp, i, collection));
        }
    
        return result;
    };
    
    Enumerate.toObject = function(collection, fun, thisp)
    {
        if ( typeof fun != "function" ) {
            throw new TypeError();
        }
    
        var result = {};
    
        var fc = new Enumerator(collection);
        for ( ; ! fc.atEnd(); fc.moveNext()) {
            var i = fc.item();
            var r = fun.call(thisp, i, collection);
            result[r.key] = r.value;
        }
    
        return result;
    };
    
    Enumerate.forItems = function(collection, fun, thisp)
    {
        if ( typeof fun != "function" ) {
            throw new TypeError();
        }
    
        var fc = new Enumerator(collection);
        for ( ; ! fc.atEnd(); fc.moveNext()) {
            var i = fc.item();
            fun.call(thisp, i, collection);
        }
    };
    Last edited by siberia-man; 10-14-2010 at 12:47 PM.


 

Posting Permissions

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