in Ox.walk, pass array of keys to iterator; rename vars
This commit is contained in:
parent
42923bedf1
commit
7f7a5aa44c
1 changed files with 145 additions and 303 deletions
|
@ -11,8 +11,8 @@ Ox.avg <f> Returns the average of an array's values, or an object's properties
|
|||
> Ox.avg('avg is 0.1')
|
||||
0.1
|
||||
@*/
|
||||
Ox.avg = function(obj) {
|
||||
return Ox.sum(obj) / Ox.len(obj);
|
||||
Ox.avg = function(collection) {
|
||||
return Ox.sum(collection) / Ox.len(collection);
|
||||
};
|
||||
|
||||
/*@
|
||||
|
@ -24,18 +24,20 @@ Ox.clone <f> Returns a (shallow or deep) copy of an object or array
|
|||
> Ox.clone(0)
|
||||
0
|
||||
@*/
|
||||
Ox.clone = Ox.copy = function(col, deep) {
|
||||
Ox.clone = Ox.copy = function(collection, deep) {
|
||||
// fixme: copy or clone?
|
||||
var ret = Ox.isArray(col) ? [] : {};
|
||||
var ret, type = Ox.typeOf(collection);
|
||||
if (deep) {
|
||||
Ox.forEach(col, function(val, key) {
|
||||
ret[key] = ['array', 'object'].indexOf(Ox.typeOf(val)) > -1
|
||||
? Ox.clone(val, true) : val;
|
||||
ret = type == 'array' ? [] : {};
|
||||
Ox.forEach(collection, function(value, key) {
|
||||
type = Ox.typeOf(value);
|
||||
ret[key] = type == 'array' || type == 'object'
|
||||
? Ox.clone(value, true) : value;
|
||||
});
|
||||
} else {
|
||||
ret = Ox.isArray(col) ? col.slice()
|
||||
: Ox.isObject(col) ? Ox.extend({}, col)
|
||||
: col;
|
||||
ret = type == 'array' ? collection.slice()
|
||||
: type == 'object' ? Ox.extend({}, collection)
|
||||
: collection;
|
||||
}
|
||||
return ret;
|
||||
};
|
||||
|
@ -52,8 +54,10 @@ Ox.contains <f> Tests if a collection contains a value
|
|||
true
|
||||
@*/
|
||||
// FIXME: a shorter name would be nice (but IE8 doesn't like 'in')
|
||||
Ox.contains = function(col, val) {
|
||||
return (Ox.isObject(col) ? Ox.values(col) : col).indexOf(val) > -1;
|
||||
Ox.contains = function(collection, value) {
|
||||
return (
|
||||
Ox.isObject(collection) ? Ox.values(collection) : collection
|
||||
).indexOf(value) > -1;
|
||||
};
|
||||
|
||||
/*@
|
||||
|
@ -65,12 +69,12 @@ Ox.count <f> Counts the occurences of values in a collection
|
|||
> Ox.count('foo')
|
||||
{f: 1, o: 2}
|
||||
@*/
|
||||
Ox.count = function(arr) {
|
||||
var obj = {};
|
||||
Ox.forEach(arr, function(v) {
|
||||
obj[v] = (obj[v] || 0) + 1;
|
||||
Ox.count = function(collection) {
|
||||
var ret = {};
|
||||
Ox.forEach(collection, function(value) {
|
||||
ret[value] = (ret[value] || 0) + 1;
|
||||
});
|
||||
return obj;
|
||||
return ret;
|
||||
};
|
||||
|
||||
/*@
|
||||
|
@ -86,8 +90,10 @@ Ox.every <f> Tests if every element of a collection satisfies a given condition
|
|||
> Ox.every([true, true, true])
|
||||
true
|
||||
@*/
|
||||
Ox.every = function(col, fn) {
|
||||
return Ox.filter(Ox.values(col), fn || Ox.identity).length == Ox.len(col);
|
||||
Ox.every = function(collection, iterator) {
|
||||
return Ox.filter(
|
||||
Ox.values(collection), iterator || Ox.identity
|
||||
).length == Ox.len(collection);
|
||||
};
|
||||
|
||||
/*@
|
||||
|
@ -101,18 +107,18 @@ Ox.filter <f> Filters a collection by a given condition
|
|||
> Ox.filter(' foo bar ', function(v) { return v != ' '; })
|
||||
'foobar'
|
||||
@*/
|
||||
Ox.filter = function(col, fn, that) {
|
||||
var ret, type = Ox.typeOf(col);
|
||||
fn = fn || Ox.identity;
|
||||
Ox.filter = function(collection, iterator, that) {
|
||||
var ret, type = Ox.typeOf(collection);
|
||||
iterator = iterator || Ox.identity;
|
||||
if (type == 'object') {
|
||||
ret = {};
|
||||
Ox.forEach(col, function(val, key) {
|
||||
if (fn.call(that, val, key, col)) {
|
||||
ret[val] = key;
|
||||
Ox.forEach(collection, function(value, key) {
|
||||
if (iterator.call(that, value, key, collection)) {
|
||||
ret[value] = key;
|
||||
}
|
||||
});
|
||||
} else {
|
||||
ret = Ox.toArray(col).filter(fn, that);
|
||||
ret = Ox.toArray(collection).filter(iterator, that);
|
||||
if (type == 'string') {
|
||||
ret = ret.join('');
|
||||
}
|
||||
|
@ -120,26 +126,6 @@ Ox.filter = function(col, fn, that) {
|
|||
return ret;
|
||||
};
|
||||
|
||||
/*@
|
||||
Ox.find <f> Returns array elements that match a string
|
||||
Returns an array of two arrays, the first containing leading matches
|
||||
(exact match first), the second containing non-leading matches
|
||||
> Ox.find(['foo', 'bar', 'foobar', 'barfoo'], 'foo')
|
||||
[['foo', 'foobar'], ['barfoo']]
|
||||
@*/
|
||||
// fixme: wouldn't it make more sense to return just one array?
|
||||
Ox.find = function(arr, str) {
|
||||
var ret = [[], []];
|
||||
str = str.toLowerCase();
|
||||
arr.map(function(v) {
|
||||
return v.toLowerCase(); // fixme: don't loop twice!!
|
||||
}).forEach(function(v, i) {
|
||||
var index = v.indexOf(str);
|
||||
index > -1 && ret[index == 0 ? 0 : 1][v == str ? 'unshift' : 'push'](arr[i]);
|
||||
});
|
||||
return ret;
|
||||
};
|
||||
|
||||
/*@
|
||||
// FIXME: documentation is outdated!
|
||||
Ox.forEach <f> forEach loop
|
||||
|
@ -165,148 +151,74 @@ Ox.forEach <f> forEach loop
|
|||
> Ox.test.string
|
||||
"012abcfoo"
|
||||
@*/
|
||||
Ox.forEach = function(col, fn, that) {
|
||||
var i, key, type = Ox.typeOf(col);
|
||||
Ox.forEach = function(collection, iterator, that) {
|
||||
var i, key, type = Ox.typeOf(collection);
|
||||
if (type != 'array' && type != 'object') {
|
||||
col = Ox.toArray(col);
|
||||
collection = Ox.toArray(collection);
|
||||
}
|
||||
try {
|
||||
if (type == 'object') {
|
||||
for (key in col) {
|
||||
// Ox.hasOwn(obj, key) && fn.call(that, col[key], key, col);
|
||||
if (Ox.hasOwn(col, key) && fn.call(that, col[key], key, col) === false) {
|
||||
for (key in collection) {
|
||||
if (Ox.hasOwn(collection, key)) {
|
||||
// iterator.call(that, collection[key], key, collection);
|
||||
if (iterator.call(that, collection[key], key, collection) === false) {
|
||||
throw new Error('Returning false in Ox.forEach is deprecated.');
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (i = 0; i < col.length; i++) {
|
||||
// i in col && fn.call(that, col[i], i, col);
|
||||
if (i in col && fn.call(that, col[i], i, col) === false) {
|
||||
for (i = 0; i < collection.length; i++) {
|
||||
if (i in collection) {
|
||||
// iterator.call(that, collection[i], i, collection);
|
||||
if (iterator.call(that, collection[i], i, collection) === false) {
|
||||
throw new Error('Returning false in Ox.forEach is deprecated.');
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch(e) {
|
||||
if (e !== Ox.BreakError) {
|
||||
throw e;
|
||||
}
|
||||
} catch(error) {
|
||||
if (error !== Ox.BreakError) {
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
return type == 'object' ? key : i;
|
||||
};
|
||||
|
||||
/*@
|
||||
Ox.getIndexById <f> Returns the first array index of an object with a given id
|
||||
> Ox.getIndexById([{id: 'foo', str: 'Foo'}, {id: 'bar', str: 'Bar'}], 'bar')
|
||||
1
|
||||
> Ox.getIndexById([{id: 'foo', str: 'Foo'}, {id: 'bar', str: 'Bar'}], 'baz')
|
||||
-1
|
||||
@*/
|
||||
Ox.getIndexById = function(arr, id) {
|
||||
return Ox.indexOf(arr, function(obj) {
|
||||
return obj.id === id;
|
||||
});
|
||||
};
|
||||
|
||||
/*@
|
||||
Ox.getObjectById <f> Returns the first object in an array with a given id
|
||||
> Ox.getObjectById([{id: 'foo', str: 'Foo'}, {id: 'bar', str: 'Bar'}], 'bar')
|
||||
{id: "bar", str: "Bar"}
|
||||
> Ox.getObjectById([{id: 'foo', str: 'Foo'}, {id: 'bar', str: 'Bar'}], 'baz')
|
||||
null
|
||||
@*/
|
||||
Ox.getObjectById = function(arr, id) {
|
||||
var index = Ox.getIndexById(arr, id);
|
||||
return index > -1 ? arr[index] : null;
|
||||
};
|
||||
|
||||
/*@
|
||||
Ox.getset <f> Generic getter and setter function
|
||||
See examples for details.
|
||||
# Usage --------------------------------------------------------------------
|
||||
Ox.getset(options, args=[]) -> <o> all options
|
||||
Ox.getset(options, args=[key]) -> <*> options[key]
|
||||
Ox.getset(options, args=[key, value], callback, context) -> <f|o> context
|
||||
sets options[key] to value and calls fn(key, value)
|
||||
if the key/value pair was added or modified
|
||||
Ox.getset(options, args=[{key: value}], callback, context) -> <f|o> context
|
||||
sets multiple options and calls fn(key, value)
|
||||
for every key/value pair that was added or modified
|
||||
# Arguments ----------------------------------------------------------------
|
||||
options <obj> Options object (key/value pairs)
|
||||
args <arr> The arguments "array" of the caller function
|
||||
callback <fun> Callback function
|
||||
The callback is called for every key/value pair that was added or
|
||||
modified.
|
||||
key <s> Key
|
||||
value <*> Value
|
||||
context <obj> The parent object of the caller function (for chaining)
|
||||
# Examples -----------------------------------------------------------------
|
||||
<script>
|
||||
Ox.test.object = new function() {
|
||||
var options = {},
|
||||
setOption = function(key, value) {
|
||||
// handle added or modified options
|
||||
},
|
||||
that = this;
|
||||
that.options = function() {
|
||||
return Ox.getset(options, arguments, setOption, that);
|
||||
};
|
||||
return that;
|
||||
};
|
||||
</script>
|
||||
> Ox.test.object.options("key", "val").options("key")
|
||||
"val"
|
||||
> Ox.test.object.options({foo: "foo", bar: "bar"}).options()
|
||||
{"key": "val", "foo": "foo", "bar": "bar"}
|
||||
@*/
|
||||
Ox.getset = function(obj, args, callback, context) {
|
||||
var obj_ = Ox.clone(obj), ret;
|
||||
if (args.length == 0) {
|
||||
// []
|
||||
ret = obj_;
|
||||
} else if (args.length == 1 && !Ox.isObject(args[0])) {
|
||||
// [key]
|
||||
ret = Ox.clone(obj[args[0]]);
|
||||
} else {
|
||||
// [key, val] or [{key: val, ...}]
|
||||
args = Ox.makeObject(args);
|
||||
obj = Ox.extend(obj, args);
|
||||
Ox.forEach(args, function(val, key) {
|
||||
if (!obj_ || !Ox.isEqual(obj_[key], val)) {
|
||||
callback && callback(key, val);
|
||||
}
|
||||
});
|
||||
ret = context;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*@
|
||||
Ox.indexOf <f> <code>indexOf</code> with a test function
|
||||
Ox.indexOf <f> Returns the first index of a collection element that passes a test
|
||||
> Ox.indexOf([1, 2, 3], function(val) { return val % 2 == 0; })
|
||||
1
|
||||
> Ox.indexOf('fooBar', function(val) { return val == val.toUpperCase(); })
|
||||
3
|
||||
> Ox.indexOf({a: 1, b: 2, c: 3}, function(val) { return val % 2 == 0; })
|
||||
'b'
|
||||
> Ox.indexOf('FooBar', function(val) { return val == val.toUpperCase(); })
|
||||
0
|
||||
> Ox.indexOf([1, 2, 3], function(val) { return val == 0; })
|
||||
-1
|
||||
@*/
|
||||
Ox.indexOf = function(col, fn) {
|
||||
var index = Ox.forEach(col, function(val) {
|
||||
fn(val) && Ox.Break();
|
||||
Ox.indexOf = function(collection, test) {
|
||||
var index = Ox.forEach(collection, function(value) {
|
||||
test(value) && Ox.Break();
|
||||
});
|
||||
return index == col.length ? -1 : index;
|
||||
return index == collection.length ? -1 : index;
|
||||
};
|
||||
|
||||
/*@
|
||||
Ox.indicesOf <f> return indices of array elements that pass a test
|
||||
> Ox.indicesOf([1, 2, 3, 4], function(val) { return val % 2 == 0; })
|
||||
[1, 3]
|
||||
|
||||
Ox.indicesOf <f> Returns all indices of collection elements that pass a test
|
||||
> Ox.indicesOf([1, 2, 3], function(val) { return val % 2 == 1; })
|
||||
[0, 2]
|
||||
> Ox.indicesOf({a: 1, b: 2, c: 3}, function(val) { return val % 2 == 1; })
|
||||
['a', 'c']
|
||||
> Ox.indicesOf('FooBar', function(val) { return val == val.toUpperCase(); })
|
||||
[0, 3]
|
||||
> Ox.indicesOf([1, 2, 3], function(val) { return val == 0; })
|
||||
[]
|
||||
@*/
|
||||
Ox.indicesOf = function(col, fn) {
|
||||
return Ox.map(col, function(val, i) {
|
||||
return fn(val) ? i : null;
|
||||
}).filter(function(index) {
|
||||
return index !== null;
|
||||
Ox.indicesOf = function(collection, test) {
|
||||
var ret = [];
|
||||
Ox.forEach(collection, function(value, index) {
|
||||
test(value) && ret.push(index);
|
||||
});
|
||||
return ret;
|
||||
};
|
||||
|
||||
/*@
|
||||
|
@ -330,8 +242,8 @@ Ox.isEmpty <f> Tests if a value is an empty array, object or string
|
|||
> Ox.isEmpty()
|
||||
false
|
||||
@*/
|
||||
Ox.isEmpty = function(val) {
|
||||
return Ox.len(val) === 0;
|
||||
Ox.isEmpty = function(value) {
|
||||
return Ox.len(value) === 0;
|
||||
};
|
||||
|
||||
/*@
|
||||
|
@ -350,13 +262,13 @@ Ox.last <f> Gets or sets the last element of an array
|
|||
> Ox.last('123')
|
||||
'3'
|
||||
@*/
|
||||
Ox.last = function(arr, val) {
|
||||
Ox.last = function(array, value) {
|
||||
var ret;
|
||||
if (arguments.length == 1) {
|
||||
ret = arr[arr.length - 1];
|
||||
ret = array[array.length - 1];
|
||||
} else {
|
||||
arr[arr.length - 1] = val;
|
||||
ret = arr;
|
||||
array[array.length - 1] = value;
|
||||
ret = array;
|
||||
}
|
||||
return ret;
|
||||
};
|
||||
|
@ -382,59 +294,15 @@ Ox.len <f> Returns the length of an array, node list, object or string
|
|||
undefined
|
||||
@*/
|
||||
// FIXME: Ox.size() ?
|
||||
Ox.len = function(col) {
|
||||
var len, type = Ox.typeOf(col);
|
||||
Ox.len = function(collection) {
|
||||
var ret, type = Ox.typeOf(collection);
|
||||
if (
|
||||
type == 'arguments' || type == 'array'
|
||||
|| type == 'nodelist' || type == 'string'
|
||||
) {
|
||||
len = col.length;
|
||||
ret = collection.length;
|
||||
} else if (type == 'object') {
|
||||
len = Object.keys(col).length;
|
||||
}
|
||||
return len;
|
||||
};
|
||||
|
||||
/*@
|
||||
Ox.makeArray <f> Wraps any non-array in an array.
|
||||
> Ox.makeArray('foo')
|
||||
['foo']
|
||||
> Ox.makeArray(['foo'])
|
||||
['foo']
|
||||
@*/
|
||||
Ox.makeArray = function(obj) {
|
||||
var arr;
|
||||
if (Ox.isArray(obj)) {
|
||||
arr = obj;
|
||||
} else if (Ox.isArguments(obj)) {
|
||||
arr = Ox.toArray(obj);
|
||||
} else {
|
||||
arr = [obj];
|
||||
}
|
||||
return arr;
|
||||
};
|
||||
|
||||
/*@
|
||||
Ox.makeObject <f> Takes an array and returns an object
|
||||
<code>Ox.makeObject</code> is a helper for functions with two alternative
|
||||
signatures like <code>('key', 'val')</code> and <code>({key: 'val'})</code>.
|
||||
> (function() { return Ox.makeObject(arguments); }({foo: 1, bar: 2}))
|
||||
{foo: 1, bar: 2}
|
||||
> (function() { return Ox.makeObject(arguments); }('foo', 1))
|
||||
{foo: 1}
|
||||
> (function() { return Ox.makeObject(arguments); }('foo'))
|
||||
{foo: void 0}
|
||||
> (function() { return Ox.makeObject(arguments); }())
|
||||
{}
|
||||
@*/
|
||||
Ox.makeObject = function(arr) {
|
||||
var ret = {}, type = Ox.typeOf(arr[0]);
|
||||
if (type == 'object') {
|
||||
// ({foo: 'bar'})
|
||||
ret = arr[0];
|
||||
} else if (type == 'string') {
|
||||
// ('foo', 'bar')
|
||||
ret[arr[0]] = arr[1];
|
||||
ret = Object.keys(collection).length;
|
||||
}
|
||||
return ret;
|
||||
};
|
||||
|
@ -449,20 +317,18 @@ Ox.map <f> Transforms the values of an array, object or string
|
|||
{a: true, b: false, c: false}
|
||||
> Ox.map('foo', function(v) { return v.toUpperCase(); })
|
||||
'FOO'
|
||||
> Ox.map([0, 1, 2, 4], function(v, i) { return v ? i == v : null; })
|
||||
[true, true, false]
|
||||
> Ox.map([,], function(v, i) { return i; })
|
||||
[,]
|
||||
@*/
|
||||
Ox.map = function(col, fn, that) {
|
||||
var type = Ox.typeOf(col), ret;
|
||||
Ox.map = function(collection, iterator, that) {
|
||||
var ret, type = Ox.typeOf(collection);
|
||||
if (type == 'object') {
|
||||
ret = {};
|
||||
Ox.forEach(col, function(val, key) {
|
||||
ret[key] = fn.call(that, val, key, col);
|
||||
Ox.forEach(collection, function(value, key) {
|
||||
ret[key] = iterator.call(that, value, key, collection);
|
||||
});
|
||||
} else {
|
||||
ret = Ox.toArray(col).map(fn);
|
||||
ret = Ox.toArray(collection).map(iterator);
|
||||
if (type == 'string') {
|
||||
ret = ret.join('');
|
||||
}
|
||||
|
@ -479,13 +345,13 @@ Ox.max <f> Returns the maximum value of a collection
|
|||
> Ox.max('123')
|
||||
3
|
||||
@*/
|
||||
Ox.max = function(col) {
|
||||
var ret, values = Ox.values(col);
|
||||
Ox.max = function(collection) {
|
||||
var ret, values = Ox.values(collection);
|
||||
if (values.length < Ox.STACK_LENGTH) {
|
||||
ret = Math.max.apply(null, values)
|
||||
} else {
|
||||
ret = values.reduce(function(pre, val) {
|
||||
return Math.max(pre, val);
|
||||
ret = values.reduce(function(previousValue, currentValue) {
|
||||
return Math.max(previousValue, currentValue);
|
||||
}, -Infinity);
|
||||
}
|
||||
return ret;
|
||||
|
@ -500,13 +366,13 @@ Ox.min <f> Returns the minimum value of a collection
|
|||
> Ox.min('123')
|
||||
1
|
||||
@*/
|
||||
Ox.min = function(col) {
|
||||
var ret, values = Ox.values(col);
|
||||
Ox.min = function(collection) {
|
||||
var ret, values = Ox.values(collection);
|
||||
if (values.length < Ox.STACK_LENGTH) {
|
||||
ret = Math.min.apply(null, values)
|
||||
} else {
|
||||
ret = values.reduce(function(pre, val) {
|
||||
return Math.min(pre, val);
|
||||
ret = values.reduce(function(previousValue, currentValue) {
|
||||
return Math.min(previousValue, currentValue);
|
||||
}, Infinity);
|
||||
}
|
||||
return ret;
|
||||
|
@ -519,10 +385,10 @@ Ox.reverse <f> Reverses an array or string
|
|||
> Ox.reverse('foobar')
|
||||
'raboof'
|
||||
@*/
|
||||
Ox.reverse = function(col) {
|
||||
return Ox.isArray(col)
|
||||
? Ox.clone(col).reverse()
|
||||
: col.toString().split('').reverse().join('');
|
||||
Ox.reverse = function(collection) {
|
||||
return Ox.isArray(collection)
|
||||
? Ox.clone(collection).reverse()
|
||||
: collection.toString().split('').reverse().join('');
|
||||
};
|
||||
|
||||
/*@
|
||||
|
@ -563,21 +429,21 @@ Ox.shuffle <f> Randomizes the order of values within a collection
|
|||
> Ox.shuffle('123').split('').sort().join('')
|
||||
'123'
|
||||
@*/
|
||||
Ox.shuffle = function(col) {
|
||||
var keys, ret, type = Ox.typeOf(col), values;
|
||||
Ox.shuffle = function(collection) {
|
||||
var keys, ret, type = Ox.typeOf(collection), values;
|
||||
if (type == 'object') {
|
||||
keys = Object.keys(col);
|
||||
values = Ox.shuffle(Ox.values(col));
|
||||
keys = Object.keys(collection);
|
||||
values = Ox.shuffle(Ox.values(collection));
|
||||
ret = {};
|
||||
keys.forEach(function(key, i) {
|
||||
ret[key] = values[i]
|
||||
keys.forEach(function(key, index) {
|
||||
ret[key] = values[index];
|
||||
});
|
||||
} else {
|
||||
ret = [];
|
||||
Ox.toArray(col).forEach(function(v, i) {
|
||||
var random = Math.floor(Math.random() * (i + 1));
|
||||
ret[i] = ret[random];
|
||||
ret[random] = v;
|
||||
Ox.toArray(collection).forEach(function(value, index) {
|
||||
var random = Math.floor(Math.random() * (index + 1));
|
||||
ret[index] = ret[random];
|
||||
ret[random] = value;
|
||||
});
|
||||
if (type == 'string') {
|
||||
ret = ret.join('');
|
||||
|
@ -591,8 +457,8 @@ Ox.slice <f> Alias for <code>Array.prototype.slice.call</code>
|
|||
> (function() { return Ox.slice(arguments, 1, -1); }(1, 2, 3))
|
||||
[2]
|
||||
@*/
|
||||
Ox.slice = function(val, start, stop) {
|
||||
return Array.prototype.slice.call(val, start, stop);
|
||||
Ox.slice = function(value, start, stop) {
|
||||
return Array.prototype.slice.call(value, start, stop);
|
||||
};
|
||||
|
||||
/*@
|
||||
|
@ -608,10 +474,8 @@ Ox.some <f> Tests if one or more elements of a collection meet a given condition
|
|||
> Ox.some([false, null, 0, '', void 0])
|
||||
false
|
||||
@*/
|
||||
Ox.some = function(obj, fn) {
|
||||
return Ox.filter(Ox.values(obj), fn || function(v) {
|
||||
return v;
|
||||
}).length > 0;
|
||||
Ox.some = function(collection, iterator) {
|
||||
return Ox.filter(Ox.values(collection), iterator || Ox.identity).length > 0;
|
||||
};
|
||||
|
||||
/*@
|
||||
|
@ -629,44 +493,14 @@ Ox.sum <f> Returns the sum of the values of a collection
|
|||
> Ox.sum('08', -2, 'foo')
|
||||
6
|
||||
@*/
|
||||
Ox.sum = function(col) {
|
||||
var sum = 0;
|
||||
col = arguments.length > 1 ? Ox.toArray(arguments) : col;
|
||||
Ox.forEach(col, function(val) {
|
||||
val = +val;
|
||||
sum += isFinite(val) ? val : 0;
|
||||
Ox.sum = function(collection) {
|
||||
var ret = 0;
|
||||
collection = arguments.length > 1 ? Ox.toArray(arguments) : collection;
|
||||
Ox.forEach(collection, function(value) {
|
||||
value = +value;
|
||||
ret += isFinite(value) ? value : 0;
|
||||
});
|
||||
return sum;
|
||||
};
|
||||
|
||||
/*@
|
||||
Ox.toArray <f> Takes an array-like object and returns a true array
|
||||
(value) -> <a> True array
|
||||
value <*> Array-like object
|
||||
> (function() { return Ox.toArray(arguments); }("foo", "bar"))
|
||||
["foo", "bar"]
|
||||
> Ox.toArray("foo")
|
||||
["f", "o", "o"]
|
||||
> Ox.toArray({0: "f", 1: "o", 2: "o", length: 3})
|
||||
["f", "o", "o"]
|
||||
@*/
|
||||
// rewrite this so that it uses a try/catch test
|
||||
Ox.toArray = /MSIE/.test(navigator.userAgent)
|
||||
? function(col) {
|
||||
var i, len, ret = [];
|
||||
try {
|
||||
ret = Array.prototype.slice.call(col);
|
||||
} catch(e) {
|
||||
// handle MSIE NodeLists
|
||||
len = col.length;
|
||||
for (i = 0; i < len; i++) {
|
||||
ret[i] = col[i];
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
: function(col) {
|
||||
return Array.prototype.slice.call(col);
|
||||
};
|
||||
|
||||
/*@
|
||||
|
@ -678,37 +512,45 @@ Ox.values <f> Returns the values of a collection
|
|||
> Ox.values('abc')
|
||||
['a', 'b', 'c']
|
||||
> Ox.values([1,,3])
|
||||
[1, 3]
|
||||
[1,,3]
|
||||
@*/
|
||||
Ox.values = function(col) {
|
||||
var ret, type = Ox.typeOf(col);
|
||||
Ox.values = function(collection) {
|
||||
var ret, type = Ox.typeOf(collection);
|
||||
if (type == 'array') {
|
||||
ret = col;
|
||||
ret = collection;
|
||||
} else if (type == 'object') {
|
||||
ret = [];
|
||||
Ox.forEach(col, function(val) {
|
||||
ret.push(val);
|
||||
Ox.forEach(collection, function(value) {
|
||||
ret.push(value);
|
||||
});
|
||||
} else if (type == 'string') {
|
||||
ret = col.split('');
|
||||
ret = collection.split('');
|
||||
}
|
||||
return ret;
|
||||
};
|
||||
|
||||
/*@
|
||||
Ox.walk <f> Recursively walk a tree of key/value pairs
|
||||
Ox.walk <f> Iterate over a nested data structure
|
||||
<script>
|
||||
Ox.test.number = 0;
|
||||
Ox.walk({a: 1, b: {c: 2, d: 3}}, function (v) {
|
||||
Ox.test.number += Ox.isNumber(v) ? v : 0;
|
||||
Ox.walk({a: 1, b: {c: 2, d: 3}}, function (value) {
|
||||
Ox.test.number += Ox.isNumber(value) ? value : 0;
|
||||
});
|
||||
Ox.test.array = [];
|
||||
Ox.walk({a: 1, b: {c: 2, d: 3}}, function (value, keys) {
|
||||
Ox.isNumber(value) && Ox.test.array.push(keys)
|
||||
});
|
||||
</script>
|
||||
> Ox.test.number
|
||||
6
|
||||
> Ox.test.array
|
||||
[['a'], ['b', 'c'], ['b', 'd']]
|
||||
@*/
|
||||
Ox.walk = function(obj, fn) {
|
||||
Ox.forEach(obj, function(val, key) {
|
||||
fn(val, key, obj);
|
||||
Ox.walk(obj[key], fn);
|
||||
Ox.walk = function(collection, iterator, keys) {
|
||||
keys = keys || [];
|
||||
Ox.forEach(collection, function(value, key) {
|
||||
var keys_ = keys.concat(key);
|
||||
iterator(value, keys_, collection);
|
||||
Ox.walk(collection[key], iterator, keys_);
|
||||
});
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue