From e4550f501c63bf21e5e0697a3d09d257c0893dbf Mon Sep 17 00:00:00 2001 From: Paul Taylor Date: Sat, 9 Mar 2013 17:43:09 -0800 Subject: [PATCH 01/27] Adds "args", a function which returns the arguments its called with as an array. It's like identity for arguments. --- asx/src/asx/fn/args.as | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 asx/src/asx/fn/args.as diff --git a/asx/src/asx/fn/args.as b/asx/src/asx/fn/args.as new file mode 100644 index 0000000..ba75ca9 --- /dev/null +++ b/asx/src/asx/fn/args.as @@ -0,0 +1,11 @@ +package asx.fn +{ + /** + * @author ptaylor + */ + public function args(...args):Array { + return merge(args); + } +} + +internal const merge:Function = [].concat; \ No newline at end of file From 46ab042d5e95d2fa81027059f8e2bee321c4d37a Mon Sep 17 00:00:00 2001 From: Paul Taylor Date: Sat, 9 Mar 2013 17:49:57 -0800 Subject: [PATCH 02/27] Adds "distribute", a function which wraps a polyadic function and replaces it with a function that accepts a single Array that when invoked, calls the polyadic function with values in the Array as arguments. --- asx/src/asx/fn/distribute.as | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 asx/src/asx/fn/distribute.as diff --git a/asx/src/asx/fn/distribute.as b/asx/src/asx/fn/distribute.as new file mode 100644 index 0000000..055f634 --- /dev/null +++ b/asx/src/asx/fn/distribute.as @@ -0,0 +1,11 @@ +package asx.fn +{ + /** + * @author ptaylor + */ + public function distribute(fn:Function):Function { + return function(array:Array):* { + return fn.apply(null, array); + } + } +} \ No newline at end of file From 231573d3e39db52b55993c9015ed970366366745 Mon Sep 17 00:00:00 2001 From: Paul Taylor Date: Sat, 9 Mar 2013 17:50:26 -0800 Subject: [PATCH 03/27] Adds definition to the _ variable such that the AVM won't cast it to false-y values. --- asx/src/asx/fn/_.as | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/asx/src/asx/fn/_.as b/asx/src/asx/fn/_.as index ebf25eb..37a9ea0 100644 --- a/asx/src/asx/fn/_.as +++ b/asx/src/asx/fn/_.as @@ -5,5 +5,7 @@ package asx.fn { * * @see asx.fn.partial */ - public var _:* = undefined; + // don't use undefined because the AVM automatically casts undefined to + // false-y values and we lose the uniqueness of the constant; + public var _:Object = {}; } From b530ea9fb79bb2500b81f6840cb06444a5cd9c87 Mon Sep 17 00:00:00 2001 From: Paul Taylor Date: Sat, 9 Mar 2013 17:50:55 -0800 Subject: [PATCH 04/27] Adds "newInstance_", a version of newInstance that can be partially applied. --- asx/src/asx/object/newInstance_.as | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 asx/src/asx/object/newInstance_.as diff --git a/asx/src/asx/object/newInstance_.as b/asx/src/asx/object/newInstance_.as new file mode 100644 index 0000000..fb3ee1f --- /dev/null +++ b/asx/src/asx/object/newInstance_.as @@ -0,0 +1,26 @@ +package asx.object { + + import flash.errors.IllegalOperationError; + + /** + * Creates a new instance of a given Class, passing in a variable number of constructor args. + */ + public function newInstance_(klass:Class, ...args):Object { + switch (args.length) { + case 0: { return new klass(); } + case 1: { return new klass(args[0]); } + case 2: { return new klass(args[0], args[1]); } + case 3: { return new klass(args[0], args[1], args[2]); } + case 4: { return new klass(args[0], args[1], args[2], args[3]); } + case 5: { return new klass(args[0], args[1], args[2], args[3], args[4]); } + case 6: { return new klass(args[0], args[1], args[2], args[3], args[4], args[5]); } + case 7: { return new klass(args[0], args[1], args[2], args[3], args[4], args[5], args[6]); } + case 8: { return new klass(args[0], args[1], args[2], args[3], args[4], args[5], args[6], args[7]); } + case 9: { return new klass(args[0], args[1], args[2], args[3], args[4], args[5], args[6], args[7], args[8]); } + case 10: { return new klass(args[0], args[1], args[2], args[3], args[4], args[5], args[6], args[7], args[8], args[9]); } + default:{ throw new IllegalOperationError("Unable to instantiate:" + klass + ", too many constructor arguments, received: " + args.join(', ')); } + } + } +} + + From 5b8f0783ae78300741771a6a9edb286480f81f3e Mon Sep 17 00:00:00 2001 From: Paul Taylor Date: Sat, 9 Mar 2013 17:52:16 -0800 Subject: [PATCH 05/27] adds "guard", a function that guards a function from being invoked with too many arguments without you having to do know how many arguments the function accepts. --- asx/src/asx/fn/guard.as | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 asx/src/asx/fn/guard.as diff --git a/asx/src/asx/fn/guard.as b/asx/src/asx/fn/guard.as new file mode 100644 index 0000000..e0f33aa --- /dev/null +++ b/asx/src/asx/fn/guard.as @@ -0,0 +1,11 @@ +package asx.fn +{ + /** + * @author ptaylor + */ + public function guard(fn:Function, ...args):Function { + return function(...a):* { + return fn.apply(null, a.slice(0, fn.length || a.length)); + } + } +} \ No newline at end of file From 08f9783b7a1dd57a667b1b985f378f4467998ec2 Mon Sep 17 00:00:00 2001 From: Paul Taylor Date: Sun, 10 Mar 2013 14:36:29 -0700 Subject: [PATCH 06/27] Updates partial to work with the new _ definition. Passing "undefined" to the initial call and the partially applied function still works, so I believe this change is backwards compatible. --- asx/src/asx/fn/partial.as | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/asx/src/asx/fn/partial.as b/asx/src/asx/fn/partial.as index e3b88ce..93141b4 100644 --- a/asx/src/asx/fn/partial.as +++ b/asx/src/asx/fn/partial.as @@ -12,7 +12,8 @@ package asx.fn { var subpos:Array = []; var value:*; for (var i:int = 0; i < args.length; i++) { - if (args[i] === undefined) { + if (args[i] === undefined || args[i] === _) { + args[i] = _; subpos.push(i); } } @@ -22,11 +23,12 @@ package asx.fn { specialized[subpos[i]] = more[i]; } for (var j:int = 0; j < specialized.length; j++) { - if (specialized[j] === undefined) { + if (specialized[j] === undefined || specialized[j] === _) { + specialized[j] = _; return partial.apply(null, [fn].concat(specialized)); } } - return fn.apply(null, specialized.slice(0, args.length)); + return fn.apply(null, specialized); } }; } From b97db91161e240fcc18960ed2dbe102102977e8a Mon Sep 17 00:00:00 2001 From: Paul Taylor Date: Sun, 10 Mar 2013 14:38:08 -0700 Subject: [PATCH 07/27] Adds "permutate", a function which returns an Array of all the possible permutations with the number of combinations supplied. permutate(array, 2) returns the cross-product, etc. --- asx/src/asx/array/permutate.as | 66 +++++++++++++++++++++++++ asx_test/src/asx/array/PermutateTest.as | 24 +++++++++ 2 files changed, 90 insertions(+) create mode 100644 asx/src/asx/array/permutate.as create mode 100644 asx_test/src/asx/array/PermutateTest.as diff --git a/asx/src/asx/array/permutate.as b/asx/src/asx/array/permutate.as new file mode 100644 index 0000000..370f29b --- /dev/null +++ b/asx/src/asx/array/permutate.as @@ -0,0 +1,66 @@ +package asx.array +{ + import flash.utils.Dictionary; + + import asx.fn._; + import asx.fn.partial; + + /** + * Returns a multi-dimensional Array of all combinations of values in the Array, + * + * + *

Example:

+ *
+ * trace(permutate([1, 2, 3], 2)); //[ [1, 1], [1, 2], [1, 3], [2, 1], [2, 2], [2, 3], [3, 1], [3, 2], [3, 3] ] + * trace(permutate([1, 2, 3], 3)); + * // yields: + * //[ + * // [0,0,0], [0,0,1], [0,0,2], + * // [0,1,0], [0,1,1], [0,1,2], + * // [0,2,0], [0,2,1], [0,2,2], + * // [1,0,0], [1,0,1], [1,0,2], + * // [1,1,0], [1,1,1], [1,1,2], + * // [1,2,0], [1,2,1], [1,2,2], + * // [2,0,0], [2,0,1], [2,0,2], + * // [2,1,0], [2,1,1], [2,1,2], + * // [2,2,0], [2,2,1], [2,2,2] + * //] + *
+ */ + public function permutate(array:Array, combinations:int = 2):Array { + + const size:int = length(array); + + combinations = (combinations < 2) ? 2 : combinations; + + if(size < 2) + return array; + + if(size < combinations) + return [array]; + + // Initialize a cache to store the permutations for each unique value. + // If we encounter that value again, we won't have to iterate, reducing + // the runtime from O(n^combinations) to O((n - duplicates)^combinations) + const cache:Dictionary = new Dictionary(); + + const permutations:Array = []; + const merge:Function = [].concat; + + const recurse:Function = function(array:Array, togo:int, values:Array):Array { + return togo < 1 ? + [values] : + merge.apply(null, map(array, function(x:Object):Array { + return recurse(array, togo - 1, values.concat(x)); + })); + }; + + // Do a merge/map instead of calling recurse so that we can cache + // the results of unique value permutations. + return merge.apply(null, map(array, function(e:*):Array { + return e in cache ? + cache[e] : + cache[e] = recurse(array, combinations - 1, [e]); + })); + } +} diff --git a/asx_test/src/asx/array/PermutateTest.as b/asx_test/src/asx/array/PermutateTest.as new file mode 100644 index 0000000..d6fc461 --- /dev/null +++ b/asx_test/src/asx/array/PermutateTest.as @@ -0,0 +1,24 @@ +package asx.array +{ + import mx.collections.ArrayCollection; + + import org.flexunit.assertThat; + import org.hamcrest.object.equalTo; + + public class PermutateTest + { + [Test] + public function permutate_returns_with_combinationsSquared_length():void { + + const array:Array = range(0, 3); + + const perm2:Array = permutate(array, 2); + const perm3:Array = permutate(array, 3); + + trace(perm3); + + assertThat(perm2.length == Math.pow(array.length, 2)); + assertThat(perm3.length == Math.pow(array.length, 3)); + } + } +} \ No newline at end of file From cefdbba09a05d5c0ab1bb63388a24bea3e90c729 Mon Sep 17 00:00:00 2001 From: Paul Taylor Date: Sun, 10 Mar 2013 14:40:32 -0700 Subject: [PATCH 08/27] Updates "sequence" to allow a return value of _, indicating the return value memo shouldn't be stored, the prior return values should be passed on to the next Function in the sequence. --- asx/src/asx/fn/sequence.as | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/asx/src/asx/fn/sequence.as b/asx/src/asx/fn/sequence.as index fc686da..a497a7d 100644 --- a/asx/src/asx/fn/sequence.as +++ b/asx/src/asx/fn/sequence.as @@ -7,10 +7,11 @@ package asx.fn { * sequence(f1, f2, f3, ...fn)(...args) == fn(...(f3(f2(f1(...args))))) */ public function sequence(...fns):Function { - + var val:*; return function(...args):Object { return inject(args, fns, function(memo:Array, fn:Function):Array { - return [fn.apply(null, memo)]; + val = fn.apply(null, memo); + return val === _ ? memo : [val]; })[0]; }; } From 4f9c52614407f16c09f8f3b6180658dcb65050c7 Mon Sep 17 00:00:00 2001 From: Paul Taylor Date: Sun, 10 Mar 2013 14:44:01 -0700 Subject: [PATCH 09/27] Updates "inject" to allow for null seeds, indicating the seed should be taken from the head of the iterable. --- asx/src/asx/array/inject.as | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/asx/src/asx/array/inject.as b/asx/src/asx/array/inject.as index 905fb3d..18dbd03 100644 --- a/asx/src/asx/array/inject.as +++ b/asx/src/asx/array/inject.as @@ -1,4 +1,5 @@ package asx.array { + import asx.fn._; /** * Injects the memo value into an iterator function that is applied to every @@ -21,11 +22,14 @@ package asx.array { * }); * */ - public function inject(memo:Object, iterable:Object, iterator:Function):Object { + public function inject(seed:Object, iterable:Object, iterator:Function):Object { var i:int = 0; var n:int = iterator.length; + var memo:Object = seed; for each (var value:Object in iterable) { - memo = iterator.apply(null, [ memo, value, i ].slice(0, Math.max(2, n))); + memo = seed == _ && i == 0 ? + value : + iterator.apply(null, [ memo, value, i ].slice(0, Math.max(2, n))); i++; } return memo; From 05968f56fed5ac3c380717ef8f009b9a2df0fd34 Mon Sep 17 00:00:00 2001 From: Paul Taylor Date: Sun, 10 Mar 2013 14:44:28 -0700 Subject: [PATCH 10/27] Updates "pluck" to allow for arguments to be passed to the plucked Function invocation. --- asx/src/asx/array/pluck.as | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/asx/src/asx/array/pluck.as b/asx/src/asx/array/pluck.as index 0314484..8761968 100644 --- a/asx/src/asx/array/pluck.as +++ b/asx/src/asx/array/pluck.as @@ -1,5 +1,7 @@ package asx.array { + import asx.fn._; + import asx.fn.partial; /** * Extracts the value of a field from every item in an Array. @@ -14,21 +16,26 @@ package asx.array * assertThat(plucked, equalTo(['waffles', 'crumpets', 'toast'])); * */ - public function pluck(iterable:Object, field:Object):Array + public function pluck(iterable:Object, field:Object, ...args):Array { var chain:Array = field is Array ? field as Array : String(field).split('.'); - return inject(iterable, chain, $pluckIt) as Array; + return inject(iterable, chain, partial($pluckIt, _, _, args)) as Array; } } import asx.array.map; +import asx.fn.callFunction; import asx.fn.callProperty; import asx.fn.getProperty; -internal function $pluckIt(iterable:Object, field:String):Array +internal function $pluckIt(iterable:Object, field:String, args:Array = null):Array { var isMethod:Boolean = !!field.match(/^.+\(\)$/); field = isMethod ? field.slice(0, -2) : field; - return map(iterable, isMethod ? callProperty(field) : getProperty(field)); + return map(iterable, + isMethod ? + callProperty.apply(null, [field].concat(args)) : + getProperty(field) + ); } From 9c5448c38e42aec51cff59667267bdd33f1e57c5 Mon Sep 17 00:00:00 2001 From: Paul Taylor Date: Sun, 10 Mar 2013 14:50:58 -0700 Subject: [PATCH 11/27] Adds "areEqual", a function which equates two or more values via strict equality. --- asx/src/asx/fn/areEqual.as | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 asx/src/asx/fn/areEqual.as diff --git a/asx/src/asx/fn/areEqual.as b/asx/src/asx/fn/areEqual.as new file mode 100644 index 0000000..db9c3b6 --- /dev/null +++ b/asx/src/asx/fn/areEqual.as @@ -0,0 +1,20 @@ +package asx.fn +{ + import asx.array.allOf; + import asx.array.head; + import asx.array.last; + import asx.array.permutate; + + /** + * @author ptaylor + */ + public function areEqual(...items):Boolean { + + if(items.length < 2) return head(items); + if(items.length == 2) return head(items) === last(items); + + const permutations:Array = permutate(items, 2); + + return allOf(permutations, distribute(areEqual)); + } +} \ No newline at end of file From 6f1b59dd7be56ce4beed1bfa7177a5121473cb6d Mon Sep 17 00:00:00 2001 From: Paul Taylor Date: Sun, 10 Mar 2013 14:52:07 -0700 Subject: [PATCH 12/27] Adds "ifElse", a function which when invoked, invokes one of two functions based on a condition function. --- asx/src/asx/fn/ifElse.as | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 asx/src/asx/fn/ifElse.as diff --git a/asx/src/asx/fn/ifElse.as b/asx/src/asx/fn/ifElse.as new file mode 100644 index 0000000..8ca5ccf --- /dev/null +++ b/asx/src/asx/fn/ifElse.as @@ -0,0 +1,13 @@ +package asx.fn +{ + /** + * @author ptaylor + */ + public function ifElse(condition:Function, then:Function, otherwise:Function):Function { + return function(...args):* { + return condition.apply(null, args) ? + then.apply(null, args) : + otherwise.apply(null, args); + } + } +} \ No newline at end of file From 4f56b6701a5a3f517578626ee89a1c7245abd613 Mon Sep 17 00:00:00 2001 From: Paul Taylor Date: Sun, 10 Mar 2013 14:53:36 -0700 Subject: [PATCH 13/27] Adds "tap", a function that accepts a function to run and a return value, and returns a function that when invoked, invokes the original function and returns the supplied return value. --- asx/src/asx/fn/tap.as | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 asx/src/asx/fn/tap.as diff --git a/asx/src/asx/fn/tap.as b/asx/src/asx/fn/tap.as new file mode 100644 index 0000000..b41e010 --- /dev/null +++ b/asx/src/asx/fn/tap.as @@ -0,0 +1,12 @@ +package asx.fn +{ + /** + * @author ptaylor + */ + public function tap(fn:Function, returnValue:*):Function { + return function(...args):* { + fn.apply(null, args); + return returnValue; + } + } +} \ No newline at end of file From 877caba7c2a2847dd18a1ef028d5e2ea7fcecd95 Mon Sep 17 00:00:00 2001 From: Paul Taylor Date: Sun, 10 Mar 2013 15:16:23 -0700 Subject: [PATCH 14/27] Fixes the "permutate" documentation to reflect the values in the example Array. --- asx/src/asx/array/permutate.as | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/asx/src/asx/array/permutate.as b/asx/src/asx/array/permutate.as index 370f29b..cbb4b2c 100644 --- a/asx/src/asx/array/permutate.as +++ b/asx/src/asx/array/permutate.as @@ -8,22 +8,21 @@ package asx.array /** * Returns a multi-dimensional Array of all combinations of values in the Array, * - * *

Example:

*
* trace(permutate([1, 2, 3], 2)); //[ [1, 1], [1, 2], [1, 3], [2, 1], [2, 2], [2, 3], [3, 1], [3, 2], [3, 3] ] * trace(permutate([1, 2, 3], 3)); * // yields: * //[ - * // [0,0,0], [0,0,1], [0,0,2], - * // [0,1,0], [0,1,1], [0,1,2], - * // [0,2,0], [0,2,1], [0,2,2], - * // [1,0,0], [1,0,1], [1,0,2], - * // [1,1,0], [1,1,1], [1,1,2], - * // [1,2,0], [1,2,1], [1,2,2], - * // [2,0,0], [2,0,1], [2,0,2], - * // [2,1,0], [2,1,1], [2,1,2], - * // [2,2,0], [2,2,1], [2,2,2] + * // [1, 1, 1], [1, 1, 2], [1, 1, 3], + * // [1, 2, 1], [1, 2, 2], [1, 2, 3], + * // [1, 3, 1], [1, 3, 2], [1, 3, 3], + * // [2, 1, 1], [2, 1, 2], [2, 1, 3], + * // [2, 2, 1], [2, 2, 2], [2, 2, 3], + * // [2, 3, 1], [2, 3, 2], [2, 3, 3], + * // [3, 1, 1], [3, 1, 2], [3, 1, 3], + * // [3, 2, 1], [3, 2, 2], [3, 2, 3], + * // [3, 3, 1], [3, 3, 2], [3, 3, 3] * //] *
*/ From c73c9dd4848c4902fb9cdfc32bdd7fcaa28079e2 Mon Sep 17 00:00:00 2001 From: Paul Taylor Date: Sat, 23 Mar 2013 21:42:09 -0400 Subject: [PATCH 15/27] Initial commit of callXMLProperty -- expand this method. --- asx/src/asx/fn/callXMLProperty.as | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 asx/src/asx/fn/callXMLProperty.as diff --git a/asx/src/asx/fn/callXMLProperty.as b/asx/src/asx/fn/callXMLProperty.as new file mode 100644 index 0000000..cf9db4a --- /dev/null +++ b/asx/src/asx/fn/callXMLProperty.as @@ -0,0 +1,18 @@ +package asx.fn +{ + /** + * @author ptaylor + */ + public function callXMLProperty(method:String, ...args):* { + return function(node:XML):* { + switch(method) { + case 'children': + return node.children(); + case 'childIndex': + return node.childIndex(); + case 'elements': + return node.elements(); + } + }; + } +} \ No newline at end of file From 61842fdf40d34afe8af8e9621478d2087f991370 Mon Sep 17 00:00:00 2001 From: Paul Taylor Date: Sat, 23 Mar 2013 21:42:28 -0400 Subject: [PATCH 16/27] Alias of "isA" --- asx/src/asx/object/isAn.as | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 asx/src/asx/object/isAn.as diff --git a/asx/src/asx/object/isAn.as b/asx/src/asx/object/isAn.as new file mode 100644 index 0000000..ed8805e --- /dev/null +++ b/asx/src/asx/object/isAn.as @@ -0,0 +1,18 @@ +package asx.object { + + /** + * Returns a function that returns true if the item is the given type. + * + * @example + * + * var numbers:Array = [1, 2, 3, null, true, false, 7].filter(isA(Number)); + * assertThat(numbers, equalTo([1, 2, 3, 7])); + * + */ + public function isAn(type:Class):Function { + return function(object:Object, ...rest):Boolean { + return object is type; + } + } +} + From 4716605b456a7e5a025ae06b003f1ea45c2b11a5 Mon Sep 17 00:00:00 2001 From: Paul Taylor Date: Sat, 23 Mar 2013 21:43:33 -0400 Subject: [PATCH 17/27] Adds property chaining to getProperty. Fixes args to merge argument sub-arrays too. --- asx/src/asx/fn/args.as | 2 +- asx/src/asx/fn/getProperty.as | 15 +++++++++++---- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/asx/src/asx/fn/args.as b/asx/src/asx/fn/args.as index ba75ca9..38b39d6 100644 --- a/asx/src/asx/fn/args.as +++ b/asx/src/asx/fn/args.as @@ -4,7 +4,7 @@ package asx.fn * @author ptaylor */ public function args(...args):Array { - return merge(args); + return merge.apply(null, args); } } diff --git a/asx/src/asx/fn/getProperty.as b/asx/src/asx/fn/getProperty.as index 32d4263..c8eb107 100644 --- a/asx/src/asx/fn/getProperty.as +++ b/asx/src/asx/fn/getProperty.as @@ -1,4 +1,5 @@ package asx.fn { + import asx.array.inject; /** * Returns a function that when called will get the property on the item. @@ -10,9 +11,15 @@ package asx.fn { * assertThat(results, equalTo([3, 2, 1])); * */ - public function getProperty(property:String):Function { - return function(item:Object, ...rest):Object { - return item[property]; - }; + public function getProperty(property:Object):Function { + var chain:Array = property is Array ? property as Array : String(property).split('.'); + + const getProp:Function = function(item:Object, field:*):Object { + return item[field]; + }; + + return function(item:Object, ...rest):Object { + return inject(item, chain, getProp); + }; } } From b6934418b89f37ac9bd8553cf5b2a5b186f3525c Mon Sep 17 00:00:00 2001 From: Paul Taylor Date: Sun, 14 Apr 2013 18:24:03 -0700 Subject: [PATCH 18/27] Fixes inGroupsOf to not return an empty array if the source array has a length that's a multiple of the group size. --- asx/src/asx/array/inGroupsOf.as | 35 ++++++++++++++++++--------------- 1 file changed, 19 insertions(+), 16 deletions(-) diff --git a/asx/src/asx/array/inGroupsOf.as b/asx/src/asx/array/inGroupsOf.as index 2ff4bbd..d64ba60 100644 --- a/asx/src/asx/array/inGroupsOf.as +++ b/asx/src/asx/array/inGroupsOf.as @@ -1,27 +1,30 @@ package asx.array { + import asx.fn.aritize; + import asx.fn.partial; + import asx.object.newInstance; + /** - * + * */ public function inGroupsOf(iterable:Object, size:int):Array { - var i:int = 0; - var group:Array = []; - var groups:Array = [group]; - - for each (var item:Object in iterable) - { - group[group.length] = item; - i++; - - if (i == size) - { - i = 0; - group = []; - groups[groups.length] = group; + if(size < 1) size = 1; + + const l:int = len(iterable); + const groups:Array = map(range(Math.ceil(l / size)), aritize(partial(newInstance, Array), 0)); + + var group:Array; + var i:int = -1; + + for each(var item:Object in iterable) { + if(++i % size == 0) { + group = groups[i / size]; } - } + group[group.length] = item; + } + return groups; } } \ No newline at end of file From 1a1c489e0a8ad9a989fe773f5ed4900ba64237e3 Mon Sep 17 00:00:00 2001 From: Paul Taylor Date: Sun, 14 Apr 2013 18:24:27 -0700 Subject: [PATCH 19/27] Fixes min/max to use the field param correctly. --- asx/src/asx/array/max.as | 14 ++++++++------ asx/src/asx/array/min.as | 14 ++++++++------ 2 files changed, 16 insertions(+), 12 deletions(-) diff --git a/asx/src/asx/array/max.as b/asx/src/asx/array/max.as index e34e236..b214a24 100644 --- a/asx/src/asx/array/max.as +++ b/asx/src/asx/array/max.as @@ -1,24 +1,26 @@ package asx.array { + import asx.fn._; + /** * Find the max item, or item with the max field value. */ public function max(iterable:Object, field:String=null):Object { - var result:Object; + var result:Object = _; var item:Object; if (field) { for each (item in iterable) { - if (!result) + if (result === _) { - result = item; + result = item[field]; } - else if (item && item[field] > result[field]) + else if (item && item[field] > result) { - result = item; + result = item[field]; } } } @@ -26,7 +28,7 @@ package asx.array { for each (item in iterable) { - if (!result) + if (result === _) { result = item; } diff --git a/asx/src/asx/array/min.as b/asx/src/asx/array/min.as index e382c33..2b559fe 100644 --- a/asx/src/asx/array/min.as +++ b/asx/src/asx/array/min.as @@ -1,24 +1,26 @@ package asx.array { + import asx.fn._; + /** * Find the min item, or item with the min field value. */ public function min(iterable:Object, field:String=null):Object { - var result:Object; + var result:Object = _; var item:Object; if (field) { for each (item in iterable) { - if (!result) + if (result === _) { - result = item; + result = item[field]; } - else if (item && item[field] < result[field]) + else if (item && item[field] < result) { - result = item; + result = item[field]; } } } @@ -26,7 +28,7 @@ package asx.array { for each (item in iterable) { - if (!result) + if (result === _) { result = item; } From 03a2920966d5f4366ba66173845f324cfc647cf7 Mon Sep 17 00:00:00 2001 From: Paul Taylor Date: Tue, 30 Apr 2013 13:33:20 -0500 Subject: [PATCH 20/27] Introduces a new method, "distribute" which accepts list of Functions and returns a function that when called, maps the arguments over the list of Functions and returns the resulting array. Renames the other "distribute" function to "apply". --- asx/src/asx/fn/apply.as | 11 +++++++++++ asx/src/asx/fn/areEqual.as | 2 +- asx/src/asx/fn/distribute.as | 8 +++++--- 3 files changed, 17 insertions(+), 4 deletions(-) create mode 100644 asx/src/asx/fn/apply.as diff --git a/asx/src/asx/fn/apply.as b/asx/src/asx/fn/apply.as new file mode 100644 index 0000000..9f680b0 --- /dev/null +++ b/asx/src/asx/fn/apply.as @@ -0,0 +1,11 @@ +package asx.fn +{ + /** + * @author ptaylor + */ + public function apply(fn:Function):Function { + return function(array:Array):* { + return fn.apply(null, array); + } + } +} \ No newline at end of file diff --git a/asx/src/asx/fn/areEqual.as b/asx/src/asx/fn/areEqual.as index db9c3b6..d418f84 100644 --- a/asx/src/asx/fn/areEqual.as +++ b/asx/src/asx/fn/areEqual.as @@ -15,6 +15,6 @@ package asx.fn const permutations:Array = permutate(items, 2); - return allOf(permutations, distribute(areEqual)); + return allOf(permutations, apply(areEqual)); } } \ No newline at end of file diff --git a/asx/src/asx/fn/distribute.as b/asx/src/asx/fn/distribute.as index 055f634..ec422b6 100644 --- a/asx/src/asx/fn/distribute.as +++ b/asx/src/asx/fn/distribute.as @@ -1,11 +1,13 @@ package asx.fn { + import asx.array.map; + /** * @author ptaylor */ - public function distribute(fn:Function):Function { - return function(array:Array):* { - return fn.apply(null, array); + public function distribute(...fns):Function { + return function(...args):Array { + return map(fns, callFunction.apply(null, args)); } } } \ No newline at end of file From cff1218615ac82c01de41dc9742f784c5f22fc95 Mon Sep 17 00:00:00 2001 From: Paul Taylor Date: Tue, 30 Apr 2013 13:34:47 -0500 Subject: [PATCH 21/27] Introduces "pull", a function that calls a getter or function with arguments for an instance when invoked. --- asx/src/asx/fn/pull.as | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 asx/src/asx/fn/pull.as diff --git a/asx/src/asx/fn/pull.as b/asx/src/asx/fn/pull.as new file mode 100644 index 0000000..0a790fe --- /dev/null +++ b/asx/src/asx/fn/pull.as @@ -0,0 +1,12 @@ +package asx.fn +{ + /** + * @author ptaylor + */ + public function pull(instance:Object, field:String, ...args):Function { + return function(...rest):* { + const val:* = instance[field]; + return val is Function ? val.apply(instance, args) : val; + } + } +} \ No newline at end of file From 5250c25a47a7167bae5a7a9aa058871072d62a82 Mon Sep 17 00:00:00 2001 From: Paul Taylor Date: Tue, 30 Apr 2013 13:35:49 -0500 Subject: [PATCH 22/27] Introduces "bindSetProp", a function that binds an instance and a setter field and returns a function that when called with a value, sets the value into the field of the instance. --- asx/src/asx/fn/bindSetProp.as | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 asx/src/asx/fn/bindSetProp.as diff --git a/asx/src/asx/fn/bindSetProp.as b/asx/src/asx/fn/bindSetProp.as new file mode 100644 index 0000000..a84e8a0 --- /dev/null +++ b/asx/src/asx/fn/bindSetProp.as @@ -0,0 +1,11 @@ +package asx.fn +{ + /** + * @author ptaylor + */ + public function bindSetProp(instance:Object, field:String):Function { + return function(val:*):void { + instance[field] = val; + }; + } +} \ No newline at end of file From e1877e24d9eb532ef9d7ade85ae5ab6f77757f96 Mon Sep 17 00:00:00 2001 From: Paul Taylor Date: Mon, 6 May 2013 16:51:48 -0700 Subject: [PATCH 23/27] Updates toDictionary to include a value selector in addition to its key selector. --- asx/src/asx/array/toDictionary.as | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/asx/src/asx/array/toDictionary.as b/asx/src/asx/array/toDictionary.as index 76434cc..af94f25 100644 --- a/asx/src/asx/array/toDictionary.as +++ b/asx/src/asx/array/toDictionary.as @@ -1,5 +1,6 @@ package asx.array { + import asx.fn.I; import asx.fn.getProperty; import flash.utils.Dictionary; @@ -20,7 +21,7 @@ package asx.array * trace(dict[3].value); // 5 * */ - public function toDictionary(iterable:Object, key:Object):Dictionary + public function toDictionary(iterable:Object, key:Object, value:Object = null):Dictionary { var dict:Dictionary = new Dictionary(); @@ -29,8 +30,10 @@ package asx.array ? key as Function : getProperty(String(key)); + var valFn:Function = value is Function ? value as Function : I; + for each (var item:Object in iterable) - dict[ keyFn(item) ] = item; + dict[ keyFn(item) ] = valFn(item); return dict; } From 8d844f8160aebed4d898901cf9a72aee08266d52 Mon Sep 17 00:00:00 2001 From: Paul Taylor Date: Mon, 6 May 2013 16:52:07 -0700 Subject: [PATCH 24/27] Introduces memoize, because everybody needs to memoize. --- asx/src/asx/fn/memoize.as | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 asx/src/asx/fn/memoize.as diff --git a/asx/src/asx/fn/memoize.as b/asx/src/asx/fn/memoize.as new file mode 100644 index 0000000..1669c29 --- /dev/null +++ b/asx/src/asx/fn/memoize.as @@ -0,0 +1,16 @@ +package asx.fn +{ + /** + * @author ptaylor + */ + public function memoize(func:Function, hasher:Function):Function { + const memo:Object = {}; + + return function(...args):* { + const key:String = hasher.apply(null, args); + return memo.hasOwnProperty(key) ? + memo[key] : + memo[key] = func.apply(null, args); + }; + } +} \ No newline at end of file From b82fe6549e31bf936c40f0c7660dc9463c8094ca Mon Sep 17 00:00:00 2001 From: Paul Taylor Date: Mon, 6 May 2013 16:52:21 -0700 Subject: [PATCH 25/27] Adds more functions to the callXMLProperty function. --- asx/src/asx/fn/callXMLProperty.as | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/asx/src/asx/fn/callXMLProperty.as b/asx/src/asx/fn/callXMLProperty.as index cf9db4a..5c84945 100644 --- a/asx/src/asx/fn/callXMLProperty.as +++ b/asx/src/asx/fn/callXMLProperty.as @@ -12,6 +12,10 @@ package asx.fn return node.childIndex(); case 'elements': return node.elements(); + case 'localName': + return node.localName(); + case 'toString': + return node.toString(); } }; } From f5491b51027311e73e9c7e9df0d9c672a794fe4c Mon Sep 17 00:00:00 2001 From: Paul Taylor Date: Thu, 13 Jun 2013 20:19:36 -0400 Subject: [PATCH 26/27] Changes how memoize checks whether memoized hash results are in the dictionary. Adds mergeSealed to merge objects without running into problems with sealed values. --- asx/src/asx/fn/memoize.as | 12 +++++++----- asx/src/asx/object/mergeSealed.as | 20 ++++++++++++++++++++ 2 files changed, 27 insertions(+), 5 deletions(-) create mode 100644 asx/src/asx/object/mergeSealed.as diff --git a/asx/src/asx/fn/memoize.as b/asx/src/asx/fn/memoize.as index 1669c29..c968320 100644 --- a/asx/src/asx/fn/memoize.as +++ b/asx/src/asx/fn/memoize.as @@ -1,16 +1,18 @@ package asx.fn { + import flash.utils.Dictionary; + /** * @author ptaylor */ public function memoize(func:Function, hasher:Function):Function { - const memo:Object = {}; + const memo:Dictionary = new Dictionary(true); return function(...args):* { - const key:String = hasher.apply(null, args); - return memo.hasOwnProperty(key) ? - memo[key] : - memo[key] = func.apply(null, args); + const key:Object = hasher.apply(null, args); + return memo[key] == null ? + memo[key] = func.apply(null, args) : + memo[key]; }; } } \ No newline at end of file diff --git a/asx/src/asx/object/mergeSealed.as b/asx/src/asx/object/mergeSealed.as new file mode 100644 index 0000000..03abcc8 --- /dev/null +++ b/asx/src/asx/object/mergeSealed.as @@ -0,0 +1,20 @@ +package asx.object +{ + /** + * @author ptaylor + */ + public function mergeSealed(target:Object, ...sources):* + { + for each (var source:* in sources) + { + for (var field:String in source) + { + if(target.hasOwnProperty(field) && !(target[field] is Function)) { + target[field] = source[field]; + } + } + } + + return target; + } +} \ No newline at end of file From 1e21302c2c3633214f902f364b4a088ed03c1a41 Mon Sep 17 00:00:00 2001 From: Paul Taylor Date: Fri, 21 Jun 2013 19:38:01 -0400 Subject: [PATCH 27/27] Allows apply to accept a null array without issue. --- asx/src/asx/fn/apply.as | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/asx/src/asx/fn/apply.as b/asx/src/asx/fn/apply.as index 9f680b0..2fb6288 100644 --- a/asx/src/asx/fn/apply.as +++ b/asx/src/asx/fn/apply.as @@ -5,7 +5,7 @@ package asx.fn */ public function apply(fn:Function):Function { return function(array:Array):* { - return fn.apply(null, array); + return fn.apply(null, array || []); } } } \ No newline at end of file