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
|
property <s|'checked'> property to check
|
||||||
@*/
|
@*/
|
||||||
|
|
||||||
|
// FIXME: Should be moved to Ox.js
|
||||||
|
|
||||||
Ox.OptionGroup = function(items, min, max, property) {
|
Ox.OptionGroup = function(items, min, max, property) {
|
||||||
|
|
||||||
var length = items.length;
|
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.
|
Ox.makeArray <f> Wraps any non-array in an array.
|
||||||
(value) -> <a> 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
|
(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) {
|
Ox.nonblockingForEach = function(collection, iterator, that, callback, ms) {
|
||||||
var i = 0, keys, last = Ox.last(arguments),
|
var i = 0, keys, last = Ox.last(arguments),
|
||||||
|
@ -76,12 +84,13 @@
|
||||||
};
|
};
|
||||||
|
|
||||||
/*@
|
/*@
|
||||||
Ox.nonblockingMap <f> Non-blocking map with synchronous iterator
|
Ox.nonblockingMap <f> Non-blocking `map` with synchronous iterator
|
||||||
(collection, iterator[, that]) -> <u> undefined
|
(collection, iterator[, that], callback[, ms]) -> <u> undefined
|
||||||
collection <a|o|s> Collection
|
collection <a|o|s> Collection
|
||||||
iterator <f> Iterator function
|
iterator <f> Iterator function
|
||||||
that <o> The iterator's this binding
|
that <o> The iterator's `this` binding
|
||||||
callback <f> Callback function
|
callback <f> Callback function
|
||||||
|
ms <n> Number of milliseconds after which to insert a `setTimeout` call
|
||||||
<script>
|
<script>
|
||||||
var time = +new Date();
|
var time = +new Date();
|
||||||
Ox.nonblockingMap(
|
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, iterator[, that], callback) -> <u> undefined
|
||||||
collection <a|o|s> Collection
|
collection <a|o|s> Collection
|
||||||
iterator <f> Iterator function
|
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, iterator[, that], callback) -> <u> undefined
|
||||||
collection <a|o|s> Collection
|
collection <a|o|s> Collection
|
||||||
iterator <f> Iterator function
|
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, iterator[, that], callback) -> <u> undefined
|
||||||
collection <a|o|s> Collection
|
collection <a|o|s> Collection
|
||||||
iterator <f> Iterator function
|
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, iterator[, that], callback) -> <u> undefined
|
||||||
collection <a|o|s> Collection
|
collection <a|o|s> Collection
|
||||||
iterator <f> Iterator function
|
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]; }())
|
> (function() { var a = ['v'], b = Ox.clone(a); a[0] = null; return b[0]; }())
|
||||||
'v'
|
'v'
|
||||||
> (function() { var a = {k: 'v'}, b = Ox.clone(a); a.k = null; return b.k; }())
|
> (function() { var a = {k: 'v'}, b = Ox.clone(a); a.k = null; return b.k; }())
|
||||||
'v'
|
'v'
|
||||||
> Ox.clone(0)
|
> Ox.clone(0)
|
||||||
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) {
|
Ox.clone = Ox.copy = function(collection, deep) {
|
||||||
// fixme: copy or clone?
|
// 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
|
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')
|
> Ox.contains(['foo', 'bar'], 'foo')
|
||||||
true
|
true
|
||||||
> Ox.contains({foo: 'bar'}, 'bar')
|
> Ox.contains({foo: 'bar'}, 'bar')
|
||||||
true
|
true
|
||||||
> Ox.contains({foo: 'bar'}, 'foo')
|
> Ox.contains({foo: 'bar'}, 'foo')
|
||||||
false
|
false
|
||||||
> Ox.contains("foobar", "bar")
|
> Ox.contains('foobar', 'bar')
|
||||||
true
|
true
|
||||||
@*/
|
@*/
|
||||||
// FIXME: a shorter name would be nice (but IE8 doesn't like 'in')
|
// 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
|
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'])
|
> Ox.count(['f', 'o', 'o'])
|
||||||
{f: 1, o: 2}
|
{f: 1, o: 2}
|
||||||
> Ox.count({a: 'f', b: 'o', c: 'o'})
|
> 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
|
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; })
|
> Ox.every([0, 1, 2], function(v, i) { return v == i; })
|
||||||
true
|
true
|
||||||
> Ox.every({a: 1, b: 2, c: 3}, function(v) { return v == 1; })
|
> 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
|
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; })
|
> Ox.filter([2, 1, 0], function(v, i) { return v == i; })
|
||||||
[1]
|
[1]
|
||||||
> Ox.filter({a: 'c', b: 'b', c: 'a'}, function(v, k) { return v == k; })
|
> 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;
|
return ret;
|
||||||
};
|
};
|
||||||
|
|
||||||
// FIXME: documentation is outdated!
|
|
||||||
/*@
|
/*@
|
||||||
Ox.forEach <f> forEach loop
|
Ox.forEach <f> forEach loop
|
||||||
`Ox.forEach()` loops over arrays, objects and strings. Returning `false`
|
`Ox.forEach` loops over arrays, objects and strings. Calling `Ox.Break`
|
||||||
from the iterator function acts like a `break` statement (unlike
|
inside the iterator or returning `false` from the iterator acts like a
|
||||||
`[].forEach()`, like `$.each()`). The arguments of the iterator function are
|
`break` statement. Unlike `Array.prototype.forEach`, which leaks its counter
|
||||||
`(value, key, index)` (more like `[].forEach()` than like `$.each()`).
|
variable to the outer scope, `Ox.forEach` returns it.
|
||||||
(collection, callback) <a|o|s> The collection
|
(collection, iterator[, that]) -> <n> Next index
|
||||||
(collection, callback, includePrototype) <a|o|s> The collection
|
collection <a|o|s> Collection
|
||||||
collection <a|o|s> An array, object or string
|
iterator <f> Iterator
|
||||||
callback <f> Iterator function
|
|
||||||
value <*> Value
|
value <*> Value
|
||||||
key <n|s> Key
|
key <n|s> Index or key
|
||||||
includePrototype <b|false> If true, include prototype properties
|
collection <a|o|s> The collection
|
||||||
|
that <o> The iterator's `this` binding
|
||||||
<script>
|
<script>
|
||||||
Ox.test.string = "";
|
Ox.test.string = "";
|
||||||
Ox.forEach(["f", "o", "o"], function(v, i) { Ox.test.string += i; });
|
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({a: 'f', b: 'o', c: 'o'}, function(v, k) { Ox.test.string += k; });
|
||||||
Ox.forEach("foo", function(v) { Ox.test.string += v; });
|
Ox.forEach("foo", function(v) { Ox.test.string += v; });
|
||||||
</script>
|
</script>
|
||||||
> Ox.test.string
|
> Ox.test.string
|
||||||
"012abcfoo"
|
"012abcfoo"
|
||||||
|
> Ox.forEach({a: 'f', b: 'o', c: 'o'}, function(v, k) { return v != 'o' });
|
||||||
|
1
|
||||||
@*/
|
@*/
|
||||||
Ox.forEach = function(collection, iterator, that) {
|
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') {
|
if (type != 'array' && type != 'object') {
|
||||||
collection = Ox.toArray(collection);
|
collection = Ox.toArray(collection);
|
||||||
}
|
}
|
||||||
|
@ -166,6 +186,7 @@ Ox.forEach = function(collection, iterator, that) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
i++;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for (i = 0; i < collection.length; i++) {
|
for (i = 0; i < collection.length; i++) {
|
||||||
|
@ -183,7 +204,7 @@ Ox.forEach = function(collection, iterator, that) {
|
||||||
throw error;
|
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) {
|
var index = Ox.forEach(collection, function(value) {
|
||||||
test(value) && Ox.Break();
|
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;
|
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
|
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
|
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
|
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; })
|
> Ox.map([2, 1, 0], function(v, i) { return v == i; })
|
||||||
[false, true, false]
|
[false, true, false]
|
||||||
> Ox.map({a: 'b', b: 'b', c: 'b'}, function(v, k) { return v == k; })
|
> 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('');
|
: 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 <f> Randomizes the order of values within a collection
|
||||||
> Ox.shuffle([1, 2, 3]).length
|
> 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
|
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; })
|
> Ox.some([2, 1, 0], function(i, v) { return i == v; })
|
||||||
true
|
true
|
||||||
> Ox.some({a: 1, b: 2, c: 3}, function(v) { return v == 1; })
|
> 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
|
Ox.values <f> Returns the values of a collection
|
||||||
|
(collection) -> <a> Array of values
|
||||||
|
collection <a|o|s> Collection
|
||||||
> Ox.values([1, 2, 3])
|
> Ox.values([1, 2, 3])
|
||||||
[1, 2, 3]
|
[1, 2, 3]
|
||||||
> Ox.values({a: 1, b: 2, c: 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
|
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>
|
<script>
|
||||||
Ox.test.number = 0;
|
Ox.test.number = 0;
|
||||||
Ox.walk({a: 1, b: {c: 2, d: 3}}, function(value) {
|
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
|
> Ox.test.array
|
||||||
[['a'], ['b', 'c'], ['b', 'd']]
|
[['a'], ['b', 'c'], ['b', 'd']]
|
||||||
@*/
|
@*/
|
||||||
Ox.walk = function(collection, iterator, keys) {
|
Ox.walk = function(collection, iterator, that, keys) {
|
||||||
keys = keys || [];
|
keys = keys || [];
|
||||||
Ox.forEach(collection, function(value, key) {
|
Ox.forEach(collection, function(value, key) {
|
||||||
var keys_ = keys.concat(key);
|
var keys_ = keys.concat(key);
|
||||||
iterator(value, keys_, collection);
|
iterator.call(that, value, keys_, collection);
|
||||||
Ox.walk(collection[key], iterator, keys_);
|
Ox.walk(collection[key], iterator, that, keys_);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue