source: Dev/branches/rest-dojo-ui/client/dojox/lang/functional/fold.js @ 256

Last change on this file since 256 was 256, checked in by hendrikvanantwerpen, 13 years ago

Reworked project structure based on REST interaction and Dojo library. As
soon as this is stable, the old jQueryUI branch can be removed (it's
kept for reference).

  • Property svn:executable set to *
File size: 4.4 KB
Line 
1define(["dojo/_base/lang", "dojo/_base/array", "dojo/_base/window", "./lambda"],
2        function(lang, arr, win, df){
3
4// This module adds high-level functions and related constructs:
5//      - "fold" family of functions
6
7// Notes:
8//      - missing high-level functions are provided with the compatible API:
9//              foldl, foldl1, foldr, foldr1
10//      - missing JS standard functions are provided with the compatible API:
11//              reduce, reduceRight
12//      - the fold's counterpart: unfold
13
14// Defined methods:
15//      - take any valid lambda argument as the functional argument
16//      - operate on dense arrays
17//      - take a string as the array argument
18//      - take an iterator objects as the array argument (only foldl, foldl1, and reduce)
19
20        var empty = {};
21
22/*=====
23        var df = dojox.lang.functional;
24 =====*/
25        lang.mixin(df, {
26                // classic reduce-class functions
27                foldl: function(/*Array|String|Object*/ a, /*Function*/ f, /*Object*/ z, /*Object?*/ o){
28                        // summary: repeatedly applies a binary function to an array from left
29                        //      to right using a seed value as a starting point; returns the final
30                        //      value.
31                        if(typeof a == "string"){ a = a.split(""); }
32                        o = o || win.global; f = df.lambda(f);
33                        var i, n;
34                        if(lang.isArray(a)){
35                                // array
36                                for(i = 0, n = a.length; i < n; z = f.call(o, z, a[i], i, a), ++i);
37                        }else if(typeof a.hasNext == "function" && typeof a.next == "function"){
38                                // iterator
39                                for(i = 0; a.hasNext(); z = f.call(o, z, a.next(), i++, a));
40                        }else{
41                                // object/dictionary
42                                for(i in a){
43                                        if(!(i in empty)){
44                                                z = f.call(o, z, a[i], i, a);
45                                        }
46                                }
47                        }
48                        return z;       // Object
49                },
50                foldl1: function(/*Array|String|Object*/ a, /*Function|String|Array*/ f, /*Object?*/ o){
51                        // summary: repeatedly applies a binary function to an array from left
52                        //      to right; returns the final value.
53                        if(typeof a == "string"){ a = a.split(""); }
54                        o = o || win.global; f = df.lambda(f);
55                        var z, i, n;
56                        if(lang.isArray(a)){
57                                // array
58                                z = a[0];
59                                for(i = 1, n = a.length; i < n; z = f.call(o, z, a[i], i, a), ++i);
60                        }else if(typeof a.hasNext == "function" && typeof a.next == "function"){
61                                // iterator
62                                if(a.hasNext()){
63                                        z = a.next();
64                                        for(i = 1; a.hasNext(); z = f.call(o, z, a.next(), i++, a));
65                                }
66                        }else{
67                                // object/dictionary
68                                var first = true;
69                                for(i in a){
70                                        if(!(i in empty)){
71                                                if(first){
72                                                        z = a[i];
73                                                        first = false;
74                                                }else{
75                                                        z = f.call(o, z, a[i], i, a);
76                                                }
77                                        }
78                                }
79                        }
80                        return z;       // Object
81                },
82                foldr: function(/*Array|String*/ a, /*Function|String|Array*/ f, /*Object*/ z, /*Object?*/ o){
83                        // summary: repeatedly applies a binary function to an array from right
84                        //      to left using a seed value as a starting point; returns the final
85                        //      value.
86                        if(typeof a == "string"){ a = a.split(""); }
87                        o = o || win.global; f = df.lambda(f);
88                        for(var i = a.length; i > 0; --i, z = f.call(o, z, a[i], i, a));
89                        return z;       // Object
90                },
91                foldr1: function(/*Array|String*/ a, /*Function|String|Array*/ f, /*Object?*/ o){
92                        // summary: repeatedly applies a binary function to an array from right
93                        //      to left; returns the final value.
94                        if(typeof a == "string"){ a = a.split(""); }
95                        o = o || win.global; f = df.lambda(f);
96                        var n = a.length, z = a[n - 1], i = n - 1;
97                        for(; i > 0; --i, z = f.call(o, z, a[i], i, a));
98                        return z;       // Object
99                },
100                // JS 1.8 standard array functions, which can take a lambda as a parameter.
101                reduce: function(/*Array|String|Object*/ a, /*Function|String|Array*/ f, /*Object?*/ z){
102                        // summary: apply a function simultaneously against two values of the array
103                        //      (from left-to-right) as to reduce it to a single value.
104                        return arguments.length < 3 ? df.foldl1(a, f) : df.foldl(a, f, z);      // Object
105                },
106                reduceRight: function(/*Array|String*/ a, /*Function|String|Array*/ f, /*Object?*/ z){
107                        // summary: apply a function simultaneously against two values of the array
108                        //      (from right-to-left) as to reduce it to a single value.
109                        return arguments.length < 3 ? df.foldr1(a, f) : df.foldr(a, f, z);      // Object
110                },
111                // the fold's counterpart: unfold
112                unfold: function(/*Function|String|Array*/ pr, /*Function|String|Array*/ f,
113                                                /*Function|String|Array*/ g, /*Object*/ z, /*Object?*/ o){
114                        // summary: builds an array by unfolding a value
115                        o = o || win.global; f = df.lambda(f); g = df.lambda(g); pr = df.lambda(pr);
116                        var t = [];
117                        for(; !pr.call(o, z); t.push(f.call(o, z)), z = g.call(o, z));
118                        return t;       // Array
119                }
120        });
121});
Note: See TracBrowser for help on using the repository browser.