Permalink
Browse files

adding in wrapped iterators

  • Loading branch information...
1 parent 8bdaf48 commit d6da9400062bd3da7144c7287921dc9247ae1eb6 @phiggins42 committed Jan 25, 2011
Showing with 295 additions and 0 deletions.
  1. +1 −0 README.md
  2. +129 −0 magicArray.js
  3. +1 −0 tests/magic.js
  4. +164 −0 tests/magicArray.html
View
@@ -140,6 +140,7 @@ small utility modules. Below is an overview:
* keys.js - provides Object.keys and Object.vals as dojo.keys(Object) and dojo.vals(Obj) respectively
* layout.js - create rich UI layouts from a standard JSON definition
* magic.js - experimental. adds a Deferred-based dojo.require() and exportNS functionality
+ * magicArray.js - if your iterators were too fast, and you want forIn variants of stock Array functions, use this.
* menu.js - simple CSS ul > li type hover menu
* node.js - provides dojo.node(id) giving access to Dojo API's and DOM Node attributes directly.
* NodeList-data.js - provides a basic version of $().data with more cowbell, available in Dojo 1.6
View
@@ -0,0 +1,129 @@
+dojo.provide("plugd.magicArray");
+(function(d){
+
+ /*=====
+ plugd.magicArray = {
+ // summary: A module that overwrites various Base Dojo Array APIs
+ // with a version that branches for Objects.
+ //
+ // description:
+ //
+ // A module that overwrites various Base Dojo Array APIs
+ // with a version that branches for Objects. Does NOT check
+ // hasOwnProperty.
+ //
+ // When working with objects, the following are true:
+ //
+ // + dojo.map returns an array of return values
+ // + dojo.filter returns an object reduced by the return of the iterator
+ // + dojo.indexOf does not support startIndex
+ // + dojo.indexOf returns the key name where the value was found in the object.
+ //
+ // All iterator functions are passed the value, key and object
+ // respectively.
+ // eg:
+ // | dojo.forEach({ a:"b" }, function(val, key, ob){
+ // | console.log(key == "a"); // true
+ // | console.log(val == "b"); // true
+ // | });
+ //
+ // When working with an ArrayLike object, the original Array
+ // utility function is called and behaves in a backwards-compatible
+ // manner.
+ //
+ // OVERWRITES the following functions:
+ // dojo.forEach, dojo.map, dojo.filter, dojo.every, dojo.some, dojo.indexOf
+ //
+ // NOTE: base plugd has dojo.forIn() and dojo.each(), both of which handle Object iteration
+ // ... in fact, if base.js and this module are loaded at the same time, you'll end up
+ // wrapping a wrapper. probably.
+ };
+ =====*/
+
+ var ohyeah = true, gigidy = false,
+ omg = {
+
+ // references to functions we'll replace
+ boring: {
+ forEach: d.forEach,
+ map: d.map,
+ filter: d.filter,
+ indexOf: d.indexOf,
+ every: d.every,
+ some: d.some
+ },
+
+ // object-capable iterators:
+ rad:{
+
+ forEach: function(obj, cb, context){
+ for(var i in obj){ item(cb, obj, i, context); }
+ },
+
+ map: function(obj, cb, context){
+ var ret = [], i;
+ for(i in obj){
+ ret.push(item(cb, obj, i, context));
+ }
+ return ret; // Array
+ },
+
+ filter: function(obj, cb, context){
+ var ret = {}, it, i;
+ for(i in obj){
+ if(item(cb, obj, i, context)){
+ ret[i] = obj[i];
+ }
+ }
+ return ret; // Object
+ },
+
+ every: function(obj, cb, context){
+ for(var i in obj){
+ if(!item(cb, obj, i, context)){
+ return gigidy;
+ }
+ }
+ return ohyeah; // Boolean
+ },
+
+ some: function(obj, cb, context){
+ var ret = false, i;
+ for(i in obj){
+ if(item(cb, obj, i, context)){
+ return ohyeah;
+ }
+ }
+ return gigidy; // Boolean
+ },
+
+ indexOf: function(haystack, needle){
+ // summary: A Bit oddball. Does not support startIndex
+ // returns: The name of the key in the object where the
+ // value was found, or -1 if unfound.
+ var ret = -1;
+ omg.rad.some(haystack, function(k, v){
+ if(k === needle){
+ ret = v;
+ return ohyeah;
+ }
+ return gigidy;
+ });
+ return ret; // Integer|String
+ }
+ }
+ }
+ ;
+
+ // so they all have identical obj function sigs
+ function item(cb, obj, key, context){
+ return cb.call(context, obj[key], key, obj);
+ }
+
+ d.forEach(["forEach", "map", "filter", "some", "indexOf", "every"], function(meth){
+ d[meth] = function(ar, cb, context){
+ return omg[(d.isArrayLike(ar) ? "boring" : "rad")][meth](ar, cb, context);
+ }
+ });
+
+})(dojo)
View
@@ -1,4 +1,5 @@
dojo.provide("plugd.tests.magic");
if(dojo.isBrowser){
doh.registerUrl("plugd.tests.magic", dojo.moduleUrl("plugd.tests", "magic.html"));
+ doh.registerUrl("plugd.tests.magicArray", dojo.moduleUrl("plugd.tests", "magicArray.html"));
}
View
@@ -0,0 +1,164 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+ "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+ <head>
+ <title>Testing plugd Array wrappers</title>
+
+ <style type="text/css">
+ .thing {
+ margin:0; padding:0;
+ width:200px;
+ height:200px;
+ }
+ .cb {
+ height:100px;
+ width:400px;
+ padding:20px;
+ }
+ </style>
+
+ <script type="text/javascript" src="../../dojo/dojo.js" djConfig="isDebug: true"></script>
+
+ <script type="text/javascript">
+ dojo.require("doh.runner");
+ dojo.require("plugd.magicArray");
+ dojo.ready(function(){
+
+ var stockOb = { a:1, b:2, c: 3, d:4 },
+ stockAr = [ 1, 2, 3, 4 ],
+ thisObj = {
+ right: true
+ }
+ ;
+
+ doh.register("t",
+ [
+ function some(t){
+
+ var ret = dojo.some(stockAr, function(item, index, ar){
+ t.is(ar[index], item);
+ return item == 4;
+ });
+
+ t.t(ret);
+
+ var x = 1;
+ var ret2 = dojo.some(stockOb, function(val, key, obj){
+ t.is(obj[key], val);
+ t.is(x, val); x++;
+ return val == 4;
+ });
+
+ t.t(ret2);
+
+ dojo.some(stockOb, function(k,v){
+ t.t(this.right);
+ }, thisObj);
+ },
+
+ function every(t){
+
+ var it = dojo.every(stockAr, function(item, index, ar){
+ return ar[index] == item;
+ });
+
+ t.t(it);
+
+ it = dojo.every(stockOb, function(item, index, ar){
+ return ar[index] == item;
+ });
+
+ t.t(it);
+
+ dojo.every(stockOb, function(k,b){
+ t.t(this.right);
+ return true;
+ }, thisObj);
+
+ },
+
+ function map(t){
+
+ var it = dojo.map(stockAr, function(item){
+ return item - 1;
+ });
+
+ dojo.forEach(it, function(item, index){
+ t.is(item, index)
+ });
+
+ it = dojo.map(stockOb, function(item){
+ return item - 1;
+ });
+
+ dojo.forEach(it, function(item, index){
+ t.is(item, index);
+ });
+
+ dojo.map(stockOb, function(k,v){
+ return t.t(this.right);
+ }, thisObj);
+ },
+
+ function indexOf(t){
+
+ t.is(dojo.indexOf(stockOb, 1), "a");
+ t.is(dojo.indexOf(stockOb, 2), "b");
+ t.is(dojo.indexOf(stockOb, 9), -1);
+
+ t.is(0, dojo.indexOf(stockAr, 1));
+ t.is(1, dojo.indexOf(stockAr, 2));
+ t.is(-1, dojo.indexOf(stockAr, 9));
+
+
+ },
+
+ function forEach(t){
+
+ dojo.forEach(stockAr, function(item, index, ar){
+ t.is(ar[index], item, arguments);
+ });
+
+ dojo.forEach(stockOb, function(item, index, ar){
+ t.is(ar[index], item, arguments);
+ });
+
+ dojo.forEach(stockOb, function(k,v){
+ t.t(this.right);
+ }, thisObj);
+
+ },
+
+ function filter(t){
+ var filtered = dojo.filter(stockAr, function(item, index){
+ return item > 2;
+ });
+
+ t.is(2, filtered.length);
+ t.is(3, filtered[0]);
+ t.is(4, filtered[1]);
+
+ filtered = dojo.filter(stockOb, function(item, index){
+ return item > 2;
+ });
+
+ t.is(3, filtered.c);
+ t.is(4, filtered.d);
+ t.is(undefined, filtered.a);
+
+ dojo.filter(stockOb, function(k,v){
+ return t.t(this.right);
+ }, thisObj);
+
+ }
+
+ ]
+ );
+ doh.run();
+ });
+ </script>
+ </head>
+ <body>
+ <h1>Base Array AOP QuickTest</h1>
+ </body>
+</html>

0 comments on commit d6da940

Please sign in to comment.