/*@ Ox.filter Filters a collection by a given condition 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; }) {b: 'b'} > Ox.filter(' foo bar ', function(v) { return v != ' '; }) 'foobar' @*/ export function filter(collection, iterator, that) { var ret, type = Ox.typeOf(collection); iterator = iterator || Ox.identity; if (type == 'object' || type == 'storage') { ret = {}; Ox.forEach(collection, function(value, key) { if (iterator.call(that, value, key, collection)) { ret[key] = value; } }); } else { ret = Ox.slice(collection).filter(iterator, that); if (type == 'string') { ret = ret.join(''); } } return ret; }; /*@ Ox.indexOf 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({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 @*/ export function indexOf(collection, test) { var index = Ox.forEach(collection, function(value) { return !test(value); // break if test succeeds }); return Ox.isObject(collection) ? Object.keys(collection)[index] || null : index == collection.length ? -1 : index; };