Skip to content Skip to sidebar Skip to footer

How To Do Lazy Evaluation Of An Array Being Processed By A For Loop

window.onload = function () { x = ''; myArray = [ {a:'a', b:'b'}, {a:'c', b:'d'}, {a:x, b:''} ]; for (i = 0; i < myArray.length; i += 1) { x = myArray[i].a

Solution 1:

I think I figured out the answer with your help and the other thread I mentioned in the comment. Just need to wrap x in a function and then define a get function to apply to all elements:

window.onload = function () {
    functionget(e) {return (typeof e === 'function') ? e () : e; }
    var x = '';
    myArray = [ {a:'a', b:'b'}, {a:'c', b:'d'}, {a:function() {return x; }, b:''} ];
    for (i = 0; i < myArray.length; i += 1) {
        x = get(myArray[i].a) + get(myArray[i].b);
    }
    alert(x); // alerts 'cd';
}

x can be anything then. For example (x + 'xyz') will alert 'cdxyz'. So this way I can have any variable that I want evaluated later (when needed) be evaluated correctly (based on state at that point).

That's what I needed. :)

Solution 2:

var elements = [ { a:"a", b:"b"}, {a:"c", b:"d"}, {a:"e", b:"f"} ];
functiongetter(list, num) {
    var i, agg = { a: "", b: "" };
    for (i = 0; i <= num; i += 1) {
        agg.a += list[i].a;
    }
    return agg;
}

console.log(getter(elements, 0).a); // "a"console.log(getter(elements, 1).a); // "ac"console.log(getter(elements, 2).a); // "ace"

You can use a closure so you can't access the values, like:

var elements = [ { a:"a", b:"b"}, {a:"c", b:"d"}, {a:"e", b:"f"} ];
functionmake_getter(list) {
    return {
        get: function (num) {
            var i, agg = { a: "", b: "" };
            for (i = 0; i <= num; i += 1) {
                agg.a += list[i].a;
            }
            return agg;
        }
    };
}
var getter = make_getter(elements);

console.log(getter.get(0).a); // "a"console.log(getter.get(1).a); // "ac"console.log(getter.get(2).a); // "ace"

You can make different implementations of the aggregation function.

With recursion:

var elements = [ { a:"a", b:"b"}, {a:"c", b:"d"}, {a:"e", b:"f"} ];
functiongetter(list, num) {
    var i, agg = list[num];
    if (num > 0) {
        agg.a = getter(list, num-1).a + agg.a;
    }
    return agg;
}

console.log(getter(elements, 0).a); // "a"console.log(getter(elements, 1).a); // "ac"console.log(getter(elements, 2).a); // "aace" <-- note, elements are actually modified!console.log(getter(elements, 2).a); // "aaacaace" <-- note, elements are actually modified!

old answer

Since x is not an object it's value will be copied, rather than passed as a reference.

If you change your code to:

var element = { a: '', b:'' };
myArray =  [ {a:'a', b:'b'}, {a:'c', b:'d'}, element ];
for (i = 0; i < myArray.length; i += 1) {
    element.a = myArray[i].a + myArray[i].b;
}
alert(el.a);  // alerts 'cd';

You will get "cd".


This is not called lazy evaluation by the way. It's just an aggregate or something.

Post a Comment for "How To Do Lazy Evaluation Of An Array Being Processed By A For Loop"