Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Add foldl1, maximum, minimum, maximumBy and minimumBy functions.

  • Loading branch information...
commit d2f10d3f3c49b1bf1d948653269d6c0d6265a6db 1 parent 495f938
@beastaugh authored
View
12 CHANGELOG
@@ -0,0 +1,12 @@
+Udon changelog
+==============
+
+Version 1.1.0
+-------------
+
+* Added `foldl1`, `maximum`, `minimum`, `maximumBy` and `minimumBy` functions.
+
+Version 1.0.0
+-------------
+
+* Initial release.
View
5 jake.yml
@@ -23,7 +23,12 @@ packages:
- Udon.curry
- Udon.compose
- Udon.foldl
+ - Udon.foldl1
- Udon.foldr
+ - Udon.maximum
+ - Udon.minimum
+ - Udon.maximumBy
+ - Udon.minimumBy
- Udon.map
- Udon.filter
- Udon.any
View
1  site/downloads/udon-1.1.0-min.js
@@ -0,0 +1 @@
+Udon=(typeof Udon==='undefined')?{}:Udon;Udon._0=Array.prototype.slice;Udon.ncurry=function(d){if(typeof d!='number'||d<2)d=2;var e=function(a){var c=Udon._0.call(arguments,1);return function(){var b=c.concat(Udon._0.call(arguments,0));if(b.length<d){b.unshift(a);return e.apply(null,b)}else{return a.apply(null,b)}}};return e};Udon.curry=function(a){var c=a.length,d=Udon._0.call(arguments,1),e=function(){var b=d.concat(Udon._0.call(arguments,0));return b.length>=c?a.apply(null,b):Udon.curry.apply(null,[a].concat(b))};return d.length>=c?e():e};Udon.compose=function(d,e){var f=function(){var b=d.length-1,a,c=Udon._0.call(arguments,0);if(b<0)return c[0];a=d[b].apply(null,c);while(b--)a=d[b](a);return a};return typeof e=='number'&&e>1?Udon.ncurry(e)(f):f};Udon.foldl=function(b,a,c){var d=c.length,e;for(e=0;e<d;e++)a=b(a,c[e]);return a};Udon.foldl1=function(b,a){var c=a.length,d=a[0],e;for(e=1;e<c;e++)d=b(d,a[e]);return d};Udon.foldr=function(b,a,c){var d=c.length;while(d--)a=b(c[d],a);return a};Udon.maximum=function(b){return Udon.foldl1(Math.max,b)};Udon.minimum=function(b){return Udon.foldl1(Math.min,b)};Udon.maximumBy=function(c,d){var e=function(b,a){return c(b,a)===1?b:a};return Udon.foldl1(e,d)};Udon.minimumBy=function(c,d){var e=function(b,a){return c(b,a)===1?a:b};return Udon.foldl1(e,d)};Udon.map=function(b,a){var c=a.length,d=new Array(c);while(c--)d[c]=b(a[c]);return d};Udon.filter=function(b,a){var c=[],d=a.length,e,f;for(e=0;e<d;e++){f=a[e];if(b(f))c.push(f)}return c};Udon.any=function(b,a){var c=a.length;while(c--)if(b(a[c]))return true;return false};Udon.all=function(b,a){var c=a.length;while(c--)if(!b(a[c]))return false;return true};Udon.none=function(b,a){return!Udon.any(b,a)};Udon.partition=function(b,a){var c=[],d=[],e=a.length,f,g;for(f=0;f<e;f++){g=a[f];(b(g)?c:d).push(g)}return[c,d]};Udon.unfoldr=function(b,a){var c=[],d;while((d=b(a))){c.push(d[0]);a=d[1]}return c};Udon.zip=function(c,d){return Udon.zipWith(function(b,a){return[b,a]},c,d)};Udon.zipWith=function(b,a,c){var d=a.length,e=c.length,f=d>e?e:d,g=new Array(f);while(f--)g[f]=b(a[f],c[f]);return g};
View
139 site/downloads/udon-1.1.0.js
@@ -0,0 +1,139 @@
+Udon = (typeof Udon === 'undefined') ? {} : Udon;
+
+Udon._slice = Array.prototype.slice;
+
+Udon.ncurry = function(n) {
+ if (typeof n != 'number' || n < 2) n = 2;
+ var curry = function(f) {
+ var a1 = Udon._slice.call(arguments, 1);
+ return function() {
+ var a2 = a1.concat(Udon._slice.call(arguments, 0));
+ if (a2.length < n) {
+ a2.unshift(f);
+ return curry.apply(null, a2);
+ } else {
+ return f.apply(null, a2);
+ }
+ };
+ };
+ return curry;
+};
+
+Udon.curry = function(f) {
+ var ar = f.length, a1 = Udon._slice.call(arguments, 1),
+ accumulator = function() {
+ var a2 = a1.concat(Udon._slice.call(arguments, 0));
+ return a2.length >= ar ?
+ f.apply(null, a2) : Udon.curry.apply(null, [f].concat(a2));
+ };
+ return a1.length >= ar ? accumulator() : accumulator;
+};
+
+Udon.compose = function(fs, ar) {
+ var composed = function() {
+ var i = fs.length - 1, x,
+ as = Udon._slice.call(arguments, 0);
+ if (i < 0) return as[0];
+ x = fs[i].apply(null, as);
+ while (i--) x = fs[i](x);
+ return x;
+ };
+ return typeof ar == 'number' && ar > 1 ?
+ Udon.ncurry(ar)(composed) : composed;
+};
+
+Udon.foldl = function(f, z, xs) {
+ var len = xs.length, i;
+ for (i = 0; i < len; i++) z = f(z, xs[i]);
+ return z;
+};
+
+Udon.foldl1 = function(f, xs) {
+ var len = xs.length, z = xs[0], i;
+ for (i = 1; i < len; i++) z = f(z, xs[i]);
+ return z;
+};
+
+Udon.foldr = function(f, z, xs) {
+ var i = xs.length;
+ while (i--) z = f(xs[i], z);
+ return z;
+};
+
+Udon.maximum = function(xs) {
+ return Udon.foldl1(Math.max, xs);
+};
+
+Udon.minimum = function(xs) {
+ return Udon.foldl1(Math.min, xs);
+};
+
+Udon.maximumBy = function(cmp, xs) {
+ var maxBy = function(x, y) { return cmp(x, y) === 1 ? x : y; };
+ return Udon.foldl1(maxBy, xs);
+};
+
+Udon.minimumBy = function(cmp, xs) {
+ var minBy = function(x, y) { return cmp(x, y) === 1 ? y : x; };
+ return Udon.foldl1(minBy, xs);
+};
+
+Udon.map = function(f, xs) {
+ var i = xs.length, ys = new Array(i);
+ while (i--) ys[i] = f(xs[i]);
+ return ys;
+};
+
+Udon.filter = function(f, xs) {
+ var ys = [], len = xs.length, i, e;
+ for (i = 0; i < len; i++) {
+ e = xs[i];
+ if (f(e)) ys.push(e);
+ }
+ return ys;
+};
+
+Udon.any = function(p, xs) {
+ var i = xs.length;
+ while (i--) if (p(xs[i])) return true;
+ return false;
+};
+
+Udon.all = function(p, xs) {
+ var i = xs.length;
+ while (i--) if (!p(xs[i])) return false;
+ return true;
+};
+
+Udon.none = function(p, xs) {
+ return !Udon.any(p, xs);
+};
+
+Udon.partition = function(f, xs) {
+ var ts = [], fs = [], len = xs.length, i, e;
+ for (i = 0; i < len; i++) {
+ e = xs[i];
+ (f(e) ? ts : fs).push(e);
+ }
+ return [ts, fs];
+};
+
+Udon.unfoldr = function(step, seed) {
+ var output = [], result;
+ while ((result = step(seed))) {
+ output.push(result[0]);
+ seed = result[1];
+ }
+ return output;
+};
+
+Udon.zip = function(xs, ys) {
+ return Udon.zipWith(function(x, y) { return [x, y]; }, xs, ys);
+};
+
+Udon.zipWith = function(f, xs, ys) {
+ var xsl = xs.length, ysl = ys.length, i = xsl > ysl ? ysl : xsl,
+ zs = new Array(i);
+ while (i--) zs[i] = f(xs[i], ys[i]);
+ return zs;
+};
View
80 site/index.md
@@ -11,10 +11,10 @@ in JavaScript.
Downloads
---------
-Current version: **1.0.0**.
+Current version: **1.1.0**.
-* [Development version](./downloads/udon-1.0.0.js)
-* [Production version](./downloads/udon-1.0.0-min.js) 1.7kb packed, 0.7kb
+* [Development version](./downloads/udon-1.1.0.js)
+* [Production version](./downloads/udon-1.1.0-min.js) 2.1kb packed, 0.7kb
gzipped
@@ -35,7 +35,12 @@ API summary
- [`compose`](#api-compose)
* [List operations](#api-list-operations)
- [`foldl`](#api-foldl)
+ - [`foldl1`](#api-foldl1)
- [`foldr`](#api-foldr)
+ - [`maximum`](#api-maximum)
+ - [`minimum`](#api-minimum)
+ - [`maximumBy`](#api-maximumBy)
+ - [`minimumBy`](#api-minimumBy)
- [`map`](#api-map)
- [`filter`](#api-filter)
- [`any`](#api-any)
@@ -134,6 +139,20 @@ var sum = function(ns) {
};
~~~
+<h3 id="api-foldl1"><code>foldl1</code></h3>
+
+This is a version of `foldl` which uses the first element of the supplied array
+as the initial element. It thus requires the array to be nonempty.
+
+~~~{.JavaScript}
+var join = function(a, b) {
+ return a.toString() + '-' + b.toString();
+};
+
+Udon.foldl1(join, [2011, 05, 08]);
+// -> "2011-05-08"
+~~~
+
<h3 id="api-foldr"><code>foldr</code></h3>
As the name implies, `foldl` is a left-associative function, which `foldr` is
@@ -155,6 +174,61 @@ You can read more about folds [on Wikipedia][fold].
[fold]: http://en.wikipedia.org/wiki/Fold_(higher-order_function)
+<h3 id="api-maximum"><code>maximum</code></h3>
+
+Selects the largest number from an array. It uses `Math.max` under the hood so
+it won't work for e.g. strings. Use [`Udon.maximumBy`](#api-maximumBy) if you
+need your own comparison function.
+
+~~~{.JavaScript}
+Udon.maximum([1, 3, 2, 17, 12]);
+// -> 17
+~~~
+
+<h3 id="api-minimum"><code>minimum</code></h3>
+
+Selects the smallest number from an array. It uses `Math.min` under the hood so
+it won't work for e.g. strings. Use [`Udon.minimumBy`](#api-minimumBy) if you
+need your own comparison function.
+
+~~~{.JavaScript}
+Udon.maximum([1, 3, 2, 17, 12]);
+// -> 17
+~~~
+
+<h3 id="api-maximumBy"><code>maximumBy</code></h3>
+
+Uses a given comparison function to select the largest element of an array.
+Comparison functions should take two arguments, and return `0` if they are
+considered equal, `1` if the first argument is greater than the second, and
+`-1` if the second argument is greater than the first.
+
+~~~{.JavaScript}
+var longerThan = function(x, y) {
+ if (x.length === y.length) {
+ return 0;
+ } else if (x.length > y.length) {
+ return 1;
+ } else {
+ return -1;
+ }
+};
+
+Udon.maximumBy(longerThan, ["foo", "foobar", "foobarbaz"]);
+// -> "foobarbaz"
+~~~
+
+<h3 id="api-minimumBy"><code>minimumBy</code></h3>
+
+Uses a given comparison function to select the smallest element of an array.
+Comparison functions should operate the same way as those given to
+[`maximumBy`](#api-maximumBy).
+
+~~~{.JavaScript}
+Udon.minimumBy(longerThan, ["foo", "foobar", "foobarbaz"]);
+// -> "foo"
+~~~
+
<h3 id="api-map"><code>map</code></h3>
Returns the result of applying a given function to each element of a list.
View
24 src/udon.js
@@ -48,12 +48,36 @@ Udon.foldl = function(f, z, xs) {
return z;
};
+Udon.foldl1 = function(f, xs) {
+ var len = xs.length, z = xs[0], i;
+ for (i = 1; i < len; i++) z = f(z, xs[i]);
+ return z;
+};
+
Udon.foldr = function(f, z, xs) {
var i = xs.length;
while (i--) z = f(xs[i], z);
return z;
};
+Udon.maximum = function(xs) {
+ return Udon.foldl1(Math.max, xs);
+};
+
+Udon.minimum = function(xs) {
+ return Udon.foldl1(Math.min, xs);
+};
+
+Udon.maximumBy = function(cmp, xs) {
+ var maxBy = function(x, y) { return cmp(x, y) === 1 ? x : y; };
+ return Udon.foldl1(maxBy, xs);
+};
+
+Udon.minimumBy = function(cmp, xs) {
+ var minBy = function(x, y) { return cmp(x, y) === 1 ? y : x; };
+ return Udon.foldl1(minBy, xs);
+};
+
Udon.map = function(f, xs) {
var i = xs.length, ys = new Array(i);
while (i--) ys[i] = f(xs[i]);
View
63 test/specs/udon_spec.js
@@ -103,6 +103,16 @@ JS.ENV.UdonSpec = JS.Test.describe('Udon', function() { with (this) {
}});
});
+ describe('foldl1', function() {
+ it('`foldl1` can be used to implement concatenation', function() { with(this) {
+ var concat = function(a, b) {
+ return a.toString() + b.toString();
+ };
+
+ assertEqual("194317", Udon.foldl1(concat, [19, 4, 317]));
+ }});
+ });
+
describe('foldr', function() {
it('`foldr` is the identity on arrays when passed cons and []', function() { with (this) {
var xs = [1, 2, 3, 4];
@@ -149,6 +159,59 @@ JS.ENV.UdonSpec = JS.Test.describe('Udon', function() { with (this) {
}});
});
+ describe('maximum', function() {
+ it('`maximum` should return the largest number in an array', function() { with(this) {
+ var ns = [4, 1, 7, 12, -4, 0, 8];
+
+ assertEqual(12, Udon.maximum(ns));
+ }});
+ });
+
+ describe('minimum', function() {
+ it('`minimum` should return the smallest number in an array', function() { with(this) {
+ var ns = [4, 1, 7, 12, -4, 0, 8];
+
+ assertEqual(-4, Udon.minimum(ns));
+ }});
+ });
+
+ describe('maximumBy', function() {
+ it('`maximumBy` should return the maximum of an array, given some user-defined comparison', function() { with(this) {
+ var nearerZero = function(x, y) {
+ var ax = Math.abs(x),
+ ay = Math.abs(y);
+
+ if (ax === ay) {
+ return 0;
+ } else if (ax > ay) {
+ return -1;
+ } else {
+ return 1;
+ }
+ };
+
+ assertEqual(-2, Udon.maximumBy(nearerZero, [12, 15, -5, 7, 4, -2]));
+ }});
+ });
+
+ describe('minimumBy', function() {
+ it('`minimumBy` should return the minimum of an array, given some user-defined comparison', function() { with(this) {
+ var longerThan = function(a, b) {
+ var lenA = a.length, lenB = b.length;
+
+ if (lenA === lenB) {
+ return 0;
+ } else if (lenA > lenB) {
+ return 1;
+ } else {
+ return -1;
+ }
+ };
+
+ assertEqual("foo", Udon.minimumBy(longerThan, ["foo", "foobar", "foobarbaz"]));
+ }});
+ });
+
describe('map', function() {
it('`map` should return an array of the same length as that given', function() { with(this) {
var zs = [null, null, null, null];
Please sign in to comment.
Something went wrong with that request. Please try again.