make Ox.forEach(object...) return a number; remove Ox.setPropertyOnce; move Ox.last to Array.js; update documentation and tests
This commit is contained in:
parent
686df92efa
commit
ecd84770dd
4 changed files with 104 additions and 90 deletions
|
@ -10,6 +10,8 @@ Ox.OptionGroup <f> OptionGroup
|
|||
property <s|'checked'> property to check
|
||||
@*/
|
||||
|
||||
// FIXME: Should be moved to Ox.js
|
||||
|
||||
Ox.OptionGroup = function(items, min, max, property) {
|
||||
|
||||
var length = items.length;
|
||||
|
|
|
@ -457,6 +457,33 @@ Ox.indexOf = function(arr) {
|
|||
};
|
||||
*/
|
||||
|
||||
/*@
|
||||
Ox.last <f> Gets or sets the last element of an array
|
||||
Unlike `arrayWithALongName[arrayWithALongName.length - 1]`,
|
||||
`Ox.last(arrayWithALongName)` is short.
|
||||
<script>
|
||||
Ox.test.array = [1, 2, 3];
|
||||
</script>
|
||||
> Ox.last(Ox.test.array)
|
||||
3
|
||||
> Ox.last(Ox.test.array, 4)
|
||||
[1, 2, 4]
|
||||
> Ox.test.array
|
||||
[1, 2, 4]
|
||||
> Ox.last('123')
|
||||
'3'
|
||||
@*/
|
||||
Ox.last = function(array, value) {
|
||||
var ret;
|
||||
if (arguments.length == 1) {
|
||||
ret = array[array.length - 1];
|
||||
} else {
|
||||
array[array.length - 1] = value;
|
||||
ret = array;
|
||||
}
|
||||
return ret;
|
||||
};
|
||||
|
||||
/*@
|
||||
Ox.makeArray <f> Wraps any non-array in an array.
|
||||
(value) -> <a> Array
|
||||
|
|
|
@ -31,8 +31,16 @@
|
|||
};
|
||||
|
||||
/*@
|
||||
Ox.nonblockingForEach <f> Non-blocking forEach with synchronous iterator
|
||||
Ox.nonblockingForEach <f> Non-blocking `forEach` with synchronous iterator
|
||||
(col, iterator[, that], callback[, ms]) -> <u> undefined
|
||||
collection <a|o|s> Collection
|
||||
iterator <f> Iterator function
|
||||
value <*> Value
|
||||
key <n|s> Key
|
||||
collection <a|o|s> The collection
|
||||
that <o> The iterator's `this` binding
|
||||
callback <f> Callback function
|
||||
ms <n> Number of milliseconds after which to insert a `setTimeout` call
|
||||
@*/
|
||||
Ox.nonblockingForEach = function(collection, iterator, that, callback, ms) {
|
||||
var i = 0, keys, last = Ox.last(arguments),
|
||||
|
@ -76,12 +84,13 @@
|
|||
};
|
||||
|
||||
/*@
|
||||
Ox.nonblockingMap <f> Non-blocking map with synchronous iterator
|
||||
(collection, iterator[, that]) -> <u> undefined
|
||||
Ox.nonblockingMap <f> Non-blocking `map` with synchronous iterator
|
||||
(collection, iterator[, that], callback[, ms]) -> <u> undefined
|
||||
collection <a|o|s> Collection
|
||||
iterator <f> Iterator function
|
||||
that <o> The iterator's this binding
|
||||
that <o> The iterator's `this` binding
|
||||
callback <f> Callback function
|
||||
ms <n> Number of milliseconds after which to insert a `setTimeout` call
|
||||
<script>
|
||||
var time = +new Date();
|
||||
Ox.nonblockingMap(
|
||||
|
@ -114,7 +123,7 @@
|
|||
};
|
||||
|
||||
/*@
|
||||
Ox.parallelForEach <f> forEach with asynchronous iterator, running in parallel
|
||||
Ox.parallelForEach <f> `forEach` with asynchronous iterator, running in parallel
|
||||
(collection, iterator[, that], callback) -> <u> undefined
|
||||
collection <a|o|s> Collection
|
||||
iterator <f> Iterator function
|
||||
|
@ -140,7 +149,7 @@
|
|||
};
|
||||
|
||||
/*@
|
||||
Ox.parallelMap <f> Parallel map with asynchronous iterator
|
||||
Ox.parallelMap <f> Parallel `map` with asynchronous iterator
|
||||
(collection, iterator[, that], callback) -> <u> undefined
|
||||
collection <a|o|s> Collection
|
||||
iterator <f> Iterator function
|
||||
|
@ -173,7 +182,7 @@
|
|||
};
|
||||
|
||||
/*@
|
||||
Ox.serialForEach <f> forEach with asynchronous iterator, run serially
|
||||
Ox.serialForEach <f> `forEach` with asynchronous iterator, run serially
|
||||
(collection, iterator[, that], callback) -> <u> undefined
|
||||
collection <a|o|s> Collection
|
||||
iterator <f> Iterator function
|
||||
|
@ -208,7 +217,7 @@
|
|||
};
|
||||
|
||||
/*@
|
||||
Ox.serialMap <f> Serial map with asynchronous iterator
|
||||
Ox.serialMap <f> Serial `map` with asynchronous iterator
|
||||
(collection, iterator[, that], callback) -> <u> undefined
|
||||
collection <a|o|s> Collection
|
||||
iterator <f> Iterator function
|
||||
|
|
|
@ -16,13 +16,17 @@ Ox.avg = function(collection) {
|
|||
};
|
||||
|
||||
/*@
|
||||
Ox.clone <f> Returns a (shallow or deep) copy of an object or array
|
||||
Ox.clone <f> Returns a (shallow or deep) copy of an array or object
|
||||
> (function() { var a = ['v'], b = Ox.clone(a); a[0] = null; return b[0]; }())
|
||||
'v'
|
||||
> (function() { var a = {k: 'v'}, b = Ox.clone(a); a.k = null; return b.k; }())
|
||||
'v'
|
||||
> Ox.clone(0)
|
||||
0
|
||||
> (function() { var a = [[0, 1]], b = Ox.clone(a); a[0][0] = null; return b[0]; }())
|
||||
[null, 1]
|
||||
> (function() { var a = [[0, 1]], b = Ox.clone(a, true); a[0][0] = null; return b[0]; }())
|
||||
[0, 1]
|
||||
@*/
|
||||
Ox.clone = Ox.copy = function(collection, deep) {
|
||||
// fixme: copy or clone?
|
||||
|
@ -44,13 +48,16 @@ Ox.clone = Ox.copy = function(collection, deep) {
|
|||
|
||||
/*@
|
||||
Ox.contains <f> Tests if a collection contains a value
|
||||
(collection, value) -> <b> If true, the collection contains the value
|
||||
collection <a|o|s> Collection
|
||||
value <*> Any value
|
||||
> Ox.contains(['foo', 'bar'], 'foo')
|
||||
true
|
||||
> Ox.contains({foo: 'bar'}, 'bar')
|
||||
true
|
||||
> Ox.contains({foo: 'bar'}, 'foo')
|
||||
false
|
||||
> Ox.contains("foobar", "bar")
|
||||
> Ox.contains('foobar', 'bar')
|
||||
true
|
||||
@*/
|
||||
// FIXME: a shorter name would be nice (but IE8 doesn't like 'in')
|
||||
|
@ -62,6 +69,10 @@ Ox.contains = function(collection, value) {
|
|||
|
||||
/*@
|
||||
Ox.count <f> Counts the occurences of values in a collection
|
||||
(collection) -> <o> Number of occurrences per value
|
||||
(collection, value) -> <n> Number of occurrences of the given value
|
||||
collection <a|o|s> Collection
|
||||
value <*> Any value
|
||||
> Ox.count(['f', 'o', 'o'])
|
||||
{f: 1, o: 2}
|
||||
> Ox.count({a: 'f', b: 'o', c: 'o'})
|
||||
|
@ -83,7 +94,14 @@ Ox.count = function(collection, value) {
|
|||
|
||||
/*@
|
||||
Ox.every <f> Tests if every element of a collection satisfies a given condition
|
||||
Unlike `[].every()`, `Ox.every()` works for arrays, objects and strings.
|
||||
Unlike `Array.prototype.every`, `Ox.every` works for arrays, objects and
|
||||
strings.
|
||||
(collection, iterator) -> <b> True if every element passes the test
|
||||
collection <a|o|s> Collection
|
||||
iterator <f> Iterator
|
||||
value <*> Value
|
||||
key <n|s> Index or key
|
||||
collection <a|o|s> The collection
|
||||
> Ox.every([0, 1, 2], function(v, i) { return v == i; })
|
||||
true
|
||||
> Ox.every({a: 1, b: 2, c: 3}, function(v) { return v == 1; })
|
||||
|
@ -101,7 +119,8 @@ Ox.every = function(collection, iterator) {
|
|||
|
||||
/*@
|
||||
Ox.filter <f> Filters a collection by a given condition
|
||||
Unlike `[].filter()`, `Ox.filter()` works for arrays, objects and strings.
|
||||
Unlike `Array.prototype.filter`, `Ox.filter` works for arrays, objects and
|
||||
strings.
|
||||
> Ox.filter([2, 1, 0], function(v, i) { return v == i; })
|
||||
[1]
|
||||
> Ox.filter({a: 'c', b: 'b', c: 'a'}, function(v, k) { return v == k; })
|
||||
|
@ -128,31 +147,32 @@ Ox.filter = function(collection, iterator, that) {
|
|||
return ret;
|
||||
};
|
||||
|
||||
// FIXME: documentation is outdated!
|
||||
/*@
|
||||
Ox.forEach <f> forEach loop
|
||||
`Ox.forEach()` loops over arrays, objects and strings. Returning `false`
|
||||
from the iterator function acts like a `break` statement (unlike
|
||||
`[].forEach()`, like `$.each()`). The arguments of the iterator function are
|
||||
`(value, key, index)` (more like `[].forEach()` than like `$.each()`).
|
||||
(collection, callback) <a|o|s> The collection
|
||||
(collection, callback, includePrototype) <a|o|s> The collection
|
||||
collection <a|o|s> An array, object or string
|
||||
callback <f> Iterator function
|
||||
`Ox.forEach` loops over arrays, objects and strings. Calling `Ox.Break`
|
||||
inside the iterator or returning `false` from the iterator acts like a
|
||||
`break` statement. Unlike `Array.prototype.forEach`, which leaks its counter
|
||||
variable to the outer scope, `Ox.forEach` returns it.
|
||||
(collection, iterator[, that]) -> <n> Next index
|
||||
collection <a|o|s> Collection
|
||||
iterator <f> Iterator
|
||||
value <*> Value
|
||||
key <n|s> Key
|
||||
includePrototype <b|false> If true, include prototype properties
|
||||
key <n|s> Index or key
|
||||
collection <a|o|s> The collection
|
||||
that <o> The iterator's `this` binding
|
||||
<script>
|
||||
Ox.test.string = "";
|
||||
Ox.forEach(["f", "o", "o"], function(v, i) { Ox.test.string += i; });
|
||||
Ox.forEach({a: "f", b: "o", c: "o"}, function(v, k) { Ox.test.string += k; });
|
||||
Ox.forEach(['f', 'o', 'o'], function(v, i) { Ox.test.string += i; });
|
||||
Ox.forEach({a: 'f', b: 'o', c: 'o'}, function(v, k) { Ox.test.string += k; });
|
||||
Ox.forEach("foo", function(v) { Ox.test.string += v; });
|
||||
</script>
|
||||
> Ox.test.string
|
||||
"012abcfoo"
|
||||
> Ox.forEach({a: 'f', b: 'o', c: 'o'}, function(v, k) { return v != 'o' });
|
||||
1
|
||||
@*/
|
||||
Ox.forEach = function(collection, iterator, that) {
|
||||
var i, key, type = Ox.typeOf(collection);
|
||||
var i = 0, key, type = Ox.typeOf(collection);
|
||||
if (type != 'array' && type != 'object') {
|
||||
collection = Ox.toArray(collection);
|
||||
}
|
||||
|
@ -166,6 +186,7 @@ Ox.forEach = function(collection, iterator, that) {
|
|||
break;
|
||||
}
|
||||
}
|
||||
i++;
|
||||
}
|
||||
} else {
|
||||
for (i = 0; i < collection.length; i++) {
|
||||
|
@ -183,7 +204,7 @@ Ox.forEach = function(collection, iterator, that) {
|
|||
throw error;
|
||||
}
|
||||
}
|
||||
return type == 'object' ? key : i;
|
||||
return i;
|
||||
};
|
||||
|
||||
/*@
|
||||
|
@ -201,7 +222,8 @@ Ox.indexOf = function(collection, test) {
|
|||
var index = Ox.forEach(collection, function(value) {
|
||||
test(value) && Ox.Break();
|
||||
});
|
||||
return index == collection.length ? -1 : index;
|
||||
return Ox.isObject(collection) ? Object.keys(collection)[index] || null
|
||||
: index == collection.length ? -1 : index;
|
||||
};
|
||||
|
||||
/*@
|
||||
|
@ -248,33 +270,6 @@ Ox.isEmpty = function(value) {
|
|||
return Ox.len(value) === 0;
|
||||
};
|
||||
|
||||
/*@
|
||||
Ox.last <f> Gets or sets the last element of an array
|
||||
Unlike `arrayWithALongName[arrayWithALongName.length - 1]`,
|
||||
`Ox.last(arrayWithALongName)` is short.
|
||||
<script>
|
||||
Ox.test.array = [1, 2, 3];
|
||||
</script>
|
||||
> Ox.last(Ox.test.array)
|
||||
3
|
||||
> Ox.last(Ox.test.array, 4)
|
||||
[1, 2, 4]
|
||||
> Ox.test.array
|
||||
[1, 2, 4]
|
||||
> Ox.last('123')
|
||||
'3'
|
||||
@*/
|
||||
Ox.last = function(array, value) {
|
||||
var ret;
|
||||
if (arguments.length == 1) {
|
||||
ret = array[array.length - 1];
|
||||
} else {
|
||||
array[array.length - 1] = value;
|
||||
ret = array;
|
||||
}
|
||||
return ret;
|
||||
};
|
||||
|
||||
/*@
|
||||
Ox.len <f> Returns the length of an array, node list, object or string
|
||||
Not to be confused with `Ox.length`, which is the `length` property of the
|
||||
|
@ -310,7 +305,8 @@ Ox.len = function(collection) {
|
|||
|
||||
/*@
|
||||
Ox.map <f> Transforms the values of an array, object or string
|
||||
Unlike `[].map()`, `Ox.map()` works for arrays, objects and strings.
|
||||
Unlike `Array.prototype.map`, `Ox.map` works for arrays, objects and
|
||||
strings.
|
||||
> Ox.map([2, 1, 0], function(v, i) { return v == i; })
|
||||
[false, true, false]
|
||||
> Ox.map({a: 'b', b: 'b', c: 'b'}, function(v, k) { return v == k; })
|
||||
|
@ -391,36 +387,6 @@ Ox.reverse = function(collection) {
|
|||
: collection.toString().split('').reverse().join('');
|
||||
};
|
||||
|
||||
/*@
|
||||
Ox.setPropertyOnce <f> Sets a property once
|
||||
Given a array of objects, each of which has a property with a boolean
|
||||
value, this sets exactly one of these to true, and returns the index
|
||||
of the object whose property is true.
|
||||
> Ox.setPropertyOnce([{selected: false}, {selected: false}], 'selected')
|
||||
0
|
||||
> Ox.setPropertyOnce([{selected: false}, {selected: true}], 'selected')
|
||||
1
|
||||
> Ox.setPropertyOnce([{selected: true}, {selected: true}], 'selected')
|
||||
0
|
||||
@*/
|
||||
// fixme: strange name, and shouldn't it return the full array?
|
||||
// fixme: unused, there is OptionGroup (which should be part of Ox.js)
|
||||
Ox.setPropertyOnce = function(arr, str) {
|
||||
var pos = -1;
|
||||
Ox.forEach(arr, function(v, i) {
|
||||
if (pos == -1 && arr[i][str]) {
|
||||
pos = i;
|
||||
} else if (pos > -1 && arr[i][str]) {
|
||||
delete arr[i][str];
|
||||
}
|
||||
});
|
||||
if (pos == -1) {
|
||||
arr[0][str] = true;
|
||||
pos = 0;
|
||||
}
|
||||
return pos;
|
||||
};
|
||||
|
||||
/*@
|
||||
Ox.shuffle <f> Randomizes the order of values within a collection
|
||||
> Ox.shuffle([1, 2, 3]).length
|
||||
|
@ -484,7 +450,8 @@ if (
|
|||
|
||||
/*@
|
||||
Ox.some <f> Tests if one or more elements of a collection meet a given condition
|
||||
Unlike `[].some()`, `Ox.some()` works for arrays, objects and strings.
|
||||
Unlike `Array.prototype.some`, `Ox.some` works for arrays, objects and
|
||||
strings.
|
||||
> Ox.some([2, 1, 0], function(i, v) { return i == v; })
|
||||
true
|
||||
> Ox.some({a: 1, b: 2, c: 3}, function(v) { return v == 1; })
|
||||
|
@ -545,6 +512,8 @@ Ox.objectToArray = function(object, key) {
|
|||
|
||||
/*@
|
||||
Ox.values <f> Returns the values of a collection
|
||||
(collection) -> <a> Array of values
|
||||
collection <a|o|s> Collection
|
||||
> Ox.values([1, 2, 3])
|
||||
[1, 2, 3]
|
||||
> Ox.values({a: 1, b: 2, c: 3})
|
||||
|
@ -571,6 +540,13 @@ Ox.values = function(collection) {
|
|||
|
||||
/*@
|
||||
Ox.walk <f> Iterates over a nested data structure
|
||||
(collection, iterator[, that]) -> <u> undefined
|
||||
collection <a|o|s> Collection
|
||||
iterator <f> Iterator
|
||||
value <*> Value
|
||||
keys <a> Array of keys
|
||||
collection <a|o|s> The collection
|
||||
that <o> The iterator's `this` binding
|
||||
<script>
|
||||
Ox.test.number = 0;
|
||||
Ox.walk({a: 1, b: {c: 2, d: 3}}, function(value) {
|
||||
|
@ -586,11 +562,11 @@ Ox.walk <f> Iterates over a nested data structure
|
|||
> Ox.test.array
|
||||
[['a'], ['b', 'c'], ['b', 'd']]
|
||||
@*/
|
||||
Ox.walk = function(collection, iterator, keys) {
|
||||
Ox.walk = function(collection, iterator, that, keys) {
|
||||
keys = keys || [];
|
||||
Ox.forEach(collection, function(value, key) {
|
||||
var keys_ = keys.concat(key);
|
||||
iterator(value, keys_, collection);
|
||||
Ox.walk(collection[key], iterator, keys_);
|
||||
iterator.call(that, value, keys_, collection);
|
||||
Ox.walk(collection[key], iterator, that, keys_);
|
||||
});
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue