add Function.js, some updates in OxJS
This commit is contained in:
parent
80f9a1a33d
commit
1db649bd61
6 changed files with 123 additions and 90 deletions
|
@ -48,6 +48,41 @@ Ox.merge = function(arr) {
|
||||||
return arr;
|
return arr;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*@
|
||||||
|
Ox.range <f> Python-style range
|
||||||
|
(stop) -> <[n]> range
|
||||||
|
Returns an array of integers from <code>0</code> (inclusive) to
|
||||||
|
<code>stop</code> (exclusive).
|
||||||
|
(start, stop) -> <[n]> range
|
||||||
|
Returns an array of integers from <code>start</code> (inclusive) to
|
||||||
|
<code>stop</code> (exclusive).
|
||||||
|
(start, stop, step) -> <[n]> range
|
||||||
|
Returns an array of numbers from <code>start</code> (inclusive) to
|
||||||
|
<code>stop</code> (exclusive), incrementing by <code>step</step>.
|
||||||
|
start <n> Start value
|
||||||
|
stop <n> Stop value
|
||||||
|
step <n> Step value
|
||||||
|
> Ox.range(3)
|
||||||
|
[0, 1, 2]
|
||||||
|
> Ox.range(1, 4)
|
||||||
|
[1, 2, 3]
|
||||||
|
> Ox.range(3, 0)
|
||||||
|
[3, 2, 1]
|
||||||
|
> Ox.range(1, 2, 0.5)
|
||||||
|
[1, 1.5]
|
||||||
|
> Ox.range(-1, -2, -0.5)
|
||||||
|
[-1, -1.5]
|
||||||
|
@*/
|
||||||
|
Ox.range = function() {
|
||||||
|
var args = Ox.makeArray(arguments),
|
||||||
|
arr = [];
|
||||||
|
args.push(function(i) {
|
||||||
|
arr.push(i);
|
||||||
|
});
|
||||||
|
Ox.loop.apply(null, args);
|
||||||
|
return arr;
|
||||||
|
};
|
||||||
|
|
||||||
/*@
|
/*@
|
||||||
Ox.sort <f> Sorts an array, handling leading digits and ignoring capitalization
|
Ox.sort <f> Sorts an array, handling leading digits and ignoring capitalization
|
||||||
arr <a> Array
|
arr <a> Array
|
||||||
|
|
|
@ -11,7 +11,6 @@ Ox.avg <f> Returns the average of an array's values, or an object's properties
|
||||||
> Ox.avg('avg is 0.1')
|
> Ox.avg('avg is 0.1')
|
||||||
0.1
|
0.1
|
||||||
@*/
|
@*/
|
||||||
|
|
||||||
Ox.avg = function(obj) {
|
Ox.avg = function(obj) {
|
||||||
return Ox.sum(obj) / Ox.len(obj);
|
return Ox.sum(obj) / Ox.len(obj);
|
||||||
};
|
};
|
||||||
|
@ -44,9 +43,8 @@ Ox.copy <f> Returns a (shallow or deep) copy of an object or array
|
||||||
> Ox.clone(0)
|
> Ox.clone(0)
|
||||||
0
|
0
|
||||||
@*/
|
@*/
|
||||||
|
|
||||||
Ox.copy = Ox.clone = function(col, deep) {
|
Ox.copy = Ox.clone = function(col, deep) {
|
||||||
// fixme: remove references to Ox.clone
|
// fixme: copy or clone?
|
||||||
// fixme: is there any use case for shallow copy?
|
// fixme: is there any use case for shallow copy?
|
||||||
var ret = Ox.isArray(col) ? [] : {};
|
var ret = Ox.isArray(col) ? [] : {};
|
||||||
if (deep) {
|
if (deep) {
|
||||||
|
@ -109,7 +107,6 @@ Ox.filter <f> Filters a collection by a given condition
|
||||||
> Ox.filter(' foo bar ', function(v) { return v != ' '; })
|
> Ox.filter(' foo bar ', function(v) { return v != ' '; })
|
||||||
'foobar'
|
'foobar'
|
||||||
@*/
|
@*/
|
||||||
|
|
||||||
Ox.filter = function(col, fn) {
|
Ox.filter = function(col, fn) {
|
||||||
var type = Ox.typeOf(col),
|
var type = Ox.typeOf(col),
|
||||||
ret = type == 'array' ? [] : type == 'object' ? {} : '';
|
ret = type == 'array' ? [] : type == 'object' ? {} : '';
|
||||||
|
@ -285,7 +282,6 @@ Ox.getset <f> Generic getter and setter function
|
||||||
> Ox.test.object.options({foo: "foo", bar: "bar"}).options()
|
> Ox.test.object.options({foo: "foo", bar: "bar"}).options()
|
||||||
{"key": "val", "foo": "foo", "bar": "bar"}
|
{"key": "val", "foo": "foo", "bar": "bar"}
|
||||||
@*/
|
@*/
|
||||||
|
|
||||||
Ox.getset = function(obj, args, callback, context) {
|
Ox.getset = function(obj, args, callback, context) {
|
||||||
var obj_ = Ox.clone(obj), ret;
|
var obj_ = Ox.clone(obj), ret;
|
||||||
if (args.length == 0) {
|
if (args.length == 0) {
|
||||||
|
@ -322,6 +318,8 @@ Ox.isEmpty <f> Returns true if a collection is empty
|
||||||
false
|
false
|
||||||
> Ox.isEmpty(null)
|
> Ox.isEmpty(null)
|
||||||
false
|
false
|
||||||
|
> Ox.isEmpty(0)
|
||||||
|
false
|
||||||
> Ox.isEmpty()
|
> Ox.isEmpty()
|
||||||
false
|
false
|
||||||
@*/
|
@*/
|
||||||
|
@ -345,7 +343,6 @@ Ox.keys <f> Returns the keys of a collection
|
||||||
> Ox.keys('abc')
|
> Ox.keys('abc')
|
||||||
[0, 1, 2]
|
[0, 1, 2]
|
||||||
@*/
|
@*/
|
||||||
|
|
||||||
// fixme: is this really needed? arrays... ok... but strings??
|
// fixme: is this really needed? arrays... ok... but strings??
|
||||||
Ox.keys = function(obj) {
|
Ox.keys = function(obj) {
|
||||||
var keys = [];
|
var keys = [];
|
||||||
|
@ -402,47 +399,6 @@ Ox.len = function(col) {
|
||||||
: type == 'object' ? Ox.values(col).length : void 0;
|
: type == 'object' ? Ox.values(col).length : void 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*@
|
|
||||||
Ox.loop <f> For-loop, functional-style
|
|
||||||
Returning <code>false</code> from the iterator function acts like a
|
|
||||||
<code>break</code> statement. Unlike a <code>for</code> loop,
|
|
||||||
<code>Ox.loop</code> doesn't leak its counter variable to the outer scope,
|
|
||||||
but returns it.
|
|
||||||
(stop, callback) -> <n> Next value
|
|
||||||
equivalent to <code>for (var i = 0; i < stop; i++)</code>
|
|
||||||
(start, stop, callback) -> <n> Next value
|
|
||||||
equivalent to <code>for (var i = start; i < stop; i++)</code> or,
|
|
||||||
if <code>start</code> is larger than <code>stop</code>,
|
|
||||||
<code>for (var i = start; i > stop; i--)</code>
|
|
||||||
(start, stop, step, callback) -> <n> Next value
|
|
||||||
equivalent to <code>for (var i = start; i < stop; i += step)</code> or,
|
|
||||||
if <code>step</code> is negative,
|
|
||||||
<code>for (var i = start; i > stop; i += step)</code>
|
|
||||||
start <n> Start value
|
|
||||||
stop <n> Stop value (exclusive)
|
|
||||||
step <n> Step value
|
|
||||||
callback <f> Iterator function
|
|
||||||
i <n> Counter value
|
|
||||||
> Ox.loop(10, function(i) { return i != 4; })
|
|
||||||
4
|
|
||||||
> Ox.loop(0, 3, 2, function() {})
|
|
||||||
4
|
|
||||||
@*/
|
|
||||||
Ox.loop = function() {
|
|
||||||
var len = arguments.length,
|
|
||||||
start = len > 2 ? arguments[0] : 0,
|
|
||||||
stop = arguments[len > 2 ? 1 : 0],
|
|
||||||
step = len == 4 ? arguments[2] : (start <= stop ? 1 : -1),
|
|
||||||
callback = arguments[len - 1],
|
|
||||||
i;
|
|
||||||
for (i = start; step > 0 ? i < stop : i > stop; i += step) {
|
|
||||||
if (callback(i) === false) {
|
|
||||||
break;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
return i;
|
|
||||||
};
|
|
||||||
|
|
||||||
/*@
|
/*@
|
||||||
Ox.makeArray <f> Takes an array-like object and returns a true array
|
Ox.makeArray <f> Takes an array-like object and returns a true array
|
||||||
Alias for <code>Array.prototype.slice.call</code>
|
Alias for <code>Array.prototype.slice.call</code>
|
||||||
|
@ -558,41 +514,6 @@ Ox.min = function(col) {
|
||||||
return Math.min.apply(Math, Ox.values(col));
|
return Math.min.apply(Math, Ox.values(col));
|
||||||
};
|
};
|
||||||
|
|
||||||
/*@
|
|
||||||
Ox.range <f> Python-style range
|
|
||||||
(stop) -> <[n]> range
|
|
||||||
Returns an array of integers from <code>0</code> (inclusive) to
|
|
||||||
<code>stop</code> (exclusive).
|
|
||||||
(start, stop) -> <[n]> range
|
|
||||||
Returns an array of integers from <code>start</code> (inclusive) to
|
|
||||||
<code>stop</code> (exclusive).
|
|
||||||
(start, stop, step) -> <[n]> range
|
|
||||||
Returns an array of numbers from <code>start</code> (inclusive) to
|
|
||||||
<code>stop</code> (exclusive), incrementing by <code>step</step>.
|
|
||||||
start <n> Start value
|
|
||||||
stop <n> Stop value
|
|
||||||
step <n> Step value
|
|
||||||
> Ox.range(3)
|
|
||||||
[0, 1, 2]
|
|
||||||
> Ox.range(1, 4)
|
|
||||||
[1, 2, 3]
|
|
||||||
> Ox.range(3, 0)
|
|
||||||
[3, 2, 1]
|
|
||||||
> Ox.range(1, 2, 0.5)
|
|
||||||
[1, 1.5]
|
|
||||||
> Ox.range(-1, -2, -0.5)
|
|
||||||
[-1, -1.5]
|
|
||||||
@*/
|
|
||||||
Ox.range = function() {
|
|
||||||
var args = Ox.makeArray(arguments),
|
|
||||||
arr = [];
|
|
||||||
args.push(function(i) {
|
|
||||||
arr.push(i);
|
|
||||||
});
|
|
||||||
Ox.loop.apply(null, args);
|
|
||||||
return arr;
|
|
||||||
};
|
|
||||||
|
|
||||||
/*@
|
/*@
|
||||||
Ox.setPropertyOnce <f> Sets a property once
|
Ox.setPropertyOnce <f> Sets a property once
|
||||||
Given a array of objects, each of which has a property with a boolean
|
Given a array of objects, each of which has a property with a boolean
|
||||||
|
|
|
@ -70,8 +70,6 @@ Some conventions:
|
||||||
: expression;
|
: expression;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// FIXME: add memoize
|
|
||||||
|
|
||||||
// todo: check http://ejohn.org/blog/ecmascript-5-strict-mode-json-and-more/
|
// todo: check http://ejohn.org/blog/ecmascript-5-strict-mode-json-and-more/
|
||||||
// also see https://github.com/tlrobinson/narwhal/blob/master/lib/util.js
|
// also see https://github.com/tlrobinson/narwhal/blob/master/lib/util.js
|
||||||
|
|
||||||
|
@ -81,7 +79,6 @@ Ox <f> The <code>Ox</code> object
|
||||||
(value) -> <o> wrapped value
|
(value) -> <o> wrapped value
|
||||||
value <*> Any value
|
value <*> Any value
|
||||||
@*/
|
@*/
|
||||||
|
|
||||||
window.Ox = function(val) {
|
window.Ox = function(val) {
|
||||||
return Ox.wrap(val);
|
return Ox.wrap(val);
|
||||||
};
|
};
|
||||||
|
@ -103,7 +100,6 @@ Ox.load <f> Loads a module
|
||||||
callback <f> Callback function
|
callback <f> Callback function
|
||||||
success <b> If true, the module has been loaded successfully
|
success <b> If true, the module has been loaded successfully
|
||||||
@*/
|
@*/
|
||||||
|
|
||||||
Ox.load = function() {
|
Ox.load = function() {
|
||||||
var callback = arguments[arguments.length - 1],
|
var callback = arguments[arguments.length - 1],
|
||||||
counter = 0,
|
counter = 0,
|
||||||
|
@ -224,6 +220,47 @@ Ox.Log = (function() {
|
||||||
return that;
|
return that;
|
||||||
}());
|
}());
|
||||||
|
|
||||||
|
/*@
|
||||||
|
Ox.loop <f> For-loop, functional-style
|
||||||
|
Returning <code>false</code> from the iterator function acts like a
|
||||||
|
<code>break</code> statement. Unlike a <code>for</code> loop,
|
||||||
|
<code>Ox.loop</code> doesn't leak its counter variable to the outer scope,
|
||||||
|
but returns it.
|
||||||
|
(stop, callback) -> <n> Next value
|
||||||
|
equivalent to <code>for (var i = 0; i < stop; i++)</code>
|
||||||
|
(start, stop, callback) -> <n> Next value
|
||||||
|
equivalent to <code>for (var i = start; i < stop; i++)</code> or,
|
||||||
|
if <code>start</code> is larger than <code>stop</code>,
|
||||||
|
<code>for (var i = start; i > stop; i--)</code>
|
||||||
|
(start, stop, step, callback) -> <n> Next value
|
||||||
|
equivalent to <code>for (var i = start; i < stop; i += step)</code> or,
|
||||||
|
if <code>step</code> is negative,
|
||||||
|
<code>for (var i = start; i > stop; i += step)</code>
|
||||||
|
start <n> Start value
|
||||||
|
stop <n> Stop value (exclusive)
|
||||||
|
step <n> Step value
|
||||||
|
callback <f> Iterator function
|
||||||
|
i <n> Counter value
|
||||||
|
> Ox.loop(10, function(i) { return i != 4; })
|
||||||
|
4
|
||||||
|
> Ox.loop(0, 3, 2, function() {})
|
||||||
|
4
|
||||||
|
@*/
|
||||||
|
Ox.loop = function() {
|
||||||
|
var len = arguments.length,
|
||||||
|
start = len > 2 ? arguments[0] : 0,
|
||||||
|
stop = arguments[len > 2 ? 1 : 0],
|
||||||
|
step = len == 4 ? arguments[2] : (start <= stop ? 1 : -1),
|
||||||
|
callback = arguments[len - 1],
|
||||||
|
i;
|
||||||
|
for (i = start; step > 0 ? i < stop : i > stop; i += step) {
|
||||||
|
if (callback(i) === false) {
|
||||||
|
break;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return i;
|
||||||
|
};
|
||||||
|
|
||||||
/*@
|
/*@
|
||||||
Ox.print <f> Prints its arguments to the console
|
Ox.print <f> Prints its arguments to the console
|
||||||
(arg, ...) -> <s> String
|
(arg, ...) -> <s> String
|
||||||
|
|
|
@ -35,7 +35,7 @@ if (!Array.prototype.forEach) {
|
||||||
fn.call(that, arr[i], i, arr);
|
fn.call(that, arr[i], i, arr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/indexOf
|
// see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/indexOf
|
||||||
|
@ -55,7 +55,7 @@ if (!Array.prototype.indexOf) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/map
|
// see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/map
|
||||||
|
@ -74,7 +74,7 @@ if (!Array.prototype.map) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/reduce
|
// see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/reduce
|
||||||
|
@ -116,5 +116,5 @@ if (!Object.keys) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
|
|
29
source/Ox/js/Function.js
Normal file
29
source/Ox/js/Function.js
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
/*@
|
||||||
|
Ox.cache <f> Memoize a function
|
||||||
|
<script>
|
||||||
|
var f = Ox.cache(function(n) { return n * Math.random(); });
|
||||||
|
</script>
|
||||||
|
> f(10) == f(10);
|
||||||
|
true
|
||||||
|
> f(10) == f.clear()(10);
|
||||||
|
false
|
||||||
|
@*/
|
||||||
|
Ox.cache = function(fn) {
|
||||||
|
var cache = {},
|
||||||
|
ret = function() {
|
||||||
|
var key = JSON.stringify(Ox.makeArray(arguments));
|
||||||
|
return key in cache ? cache[key]
|
||||||
|
: (cache[key] = fn.apply(this, arguments));
|
||||||
|
};
|
||||||
|
ret.clear = function() {
|
||||||
|
if (arguments.length == 0) {
|
||||||
|
cache = {};
|
||||||
|
} else {
|
||||||
|
Ox.toArray(arguments).forEach(function(key) {
|
||||||
|
delete cache[key];
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
};
|
|
@ -31,6 +31,17 @@ Ox.keyOf = function(obj, val) {
|
||||||
return key;
|
return key;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*@
|
||||||
|
Ox.methods <f> Returns a sorted list of all method names of an object
|
||||||
|
> Ox.methods({a: [], b: false, f: function() {}, n: 0, o: {}, s: ''})
|
||||||
|
['f']
|
||||||
|
@*/
|
||||||
|
Ox.methods = function(obj) {
|
||||||
|
return Object.keys(obj).filter(function(key) {
|
||||||
|
return Ox.isFunction(obj[key]);
|
||||||
|
}).sort();
|
||||||
|
};
|
||||||
|
|
||||||
/*@
|
/*@
|
||||||
Ox.serialize <f> Parses an object into query parameters
|
Ox.serialize <f> Parses an object into query parameters
|
||||||
> Ox.serialize({a: 1, b: 2, c: 3})
|
> Ox.serialize({a: 1, b: 2, c: 3})
|
||||||
|
|
Loading…
Reference in a new issue