in Ox.every, use Ox.identity; faster Ox.filter; in Ox.forEach, allow for Ox.break, and use standard arguments for iterator function, remove Ox.getIndex and Ox.getObject; add Ox.indexOf; in Ox.makeObject, use Ox.typeOf; make sure Ox.max and Ox.min don't blow the stack; add Ox.slice; in Ox.values, use Ox.typeOf
This commit is contained in:
parent
bfa9394850
commit
3d4a79b6a2
1 changed files with 118 additions and 95 deletions
|
@ -92,9 +92,7 @@ Ox.every <f> Tests if every element of a collection satisfies a given condition
|
|||
true
|
||||
@*/
|
||||
Ox.every = function(col, fn) {
|
||||
return Ox.filter(Ox.values(col), fn || function(v) {
|
||||
return v;
|
||||
}).length == Ox.len(col);
|
||||
return Ox.filter(Ox.values(col), fn || Ox.identity).length == Ox.len(col);
|
||||
};
|
||||
|
||||
/*@
|
||||
|
@ -108,20 +106,21 @@ Ox.filter <f> Filters a collection by a given condition
|
|||
> Ox.filter(' foo bar ', function(v) { return v != ' '; })
|
||||
'foobar'
|
||||
@*/
|
||||
Ox.filter = function(col, fn) {
|
||||
var type = Ox.typeOf(col),
|
||||
ret = type == 'array' ? [] : type == 'object' ? {} : '';
|
||||
Ox.forEach(col, function(val, key) {
|
||||
if (fn(val, key)) {
|
||||
if (type == 'array') {
|
||||
ret.push(val);
|
||||
} else if (type == 'object') {
|
||||
ret[key] = val;
|
||||
} else {
|
||||
ret += val;
|
||||
Ox.filter = function(col, fn, that) {
|
||||
var ret, type = Ox.typeOf(col);
|
||||
if (type == 'object') {
|
||||
ret = {};
|
||||
Ox.forEach(col, function(val, key) {
|
||||
if (fn.call(that, val, key, col)) {
|
||||
ret[val] = key;
|
||||
}
|
||||
});
|
||||
} else {
|
||||
ret = Ox.toArray(col).filter(fn, that);
|
||||
if (type == 'string') {
|
||||
ret = ret.join('');
|
||||
}
|
||||
});
|
||||
}
|
||||
return ret;
|
||||
};
|
||||
|
||||
|
@ -169,82 +168,60 @@ Ox.forEach <f> forEach loop
|
|||
> Ox.test.string
|
||||
"012abcfoo"
|
||||
@*/
|
||||
// fixme: see http://stackoverflow.com/questions/2641347/javascript-array-foreach-howto-break
|
||||
// maybe throwing an exception (Ox.break()?) is better than returning false
|
||||
Ox.forEach = function(col, fn, includePrototype) {
|
||||
var ind = 0, isObject = Ox.isObject(col), key;
|
||||
// Safari will not loop through an arguments array
|
||||
col = Ox.isArguments(col) ? Ox.toArray(col) : col;
|
||||
for (key in col) {
|
||||
key = isObject ? key : parseInt(key);
|
||||
// fixme: fn.call(context, obj[key], key, obj) may be more standard...
|
||||
if ((
|
||||
includePrototype || Object.hasOwnProperty.call(col, key)
|
||||
) && fn(col[key], key, ind++) === false) {
|
||||
break;
|
||||
Ox.forEach = function(col, fn, that) {
|
||||
var i, key, type = Ox.typeOf(col);
|
||||
if (type != 'array' && type != 'object') {
|
||||
col = Ox.toArray(col);
|
||||
}
|
||||
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) {
|
||||
console.warn('Returning false in Ox.forEach is deprecated.')
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (i = 0; i < col.length; i++) {
|
||||
// fn.call(that, col[i], i, col);
|
||||
if (fn.call(that, col[i], i, col) === false) {
|
||||
console.warn('Returning false in Ox.forEach is deprecated.')
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch(e) {
|
||||
if (e !== Ox.BreakError) {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
return col;
|
||||
};
|
||||
|
||||
/*@
|
||||
Ox.getIndex <f> Returns the first array index of an object where obj[key] is val
|
||||
> Ox.getIndex([{a: 1}, {a: 2}, {a: 1}], 'a', 2)
|
||||
1
|
||||
> Ox.getIndex([{a: 1}, {a: 2}, {a: 1}], 'a', 1)
|
||||
0
|
||||
> Ox.getIndex([{a: 1}, {a: 2}, {a: 1}], 'a', 0)
|
||||
-1
|
||||
@*/
|
||||
Ox.getIndex = function(arr, key, val) {
|
||||
var ret = -1;
|
||||
Ox.forEach(arr, function(obj, ind) {
|
||||
if (obj[key] === val) {
|
||||
ret = ind;
|
||||
return false;
|
||||
}
|
||||
});
|
||||
return ret;
|
||||
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'}], 'foo')
|
||||
0
|
||||
> 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) {
|
||||
// FIXME: shouldn't this be merged into Ox.getIndex?
|
||||
return Ox.getIndex(arr, 'id', id);
|
||||
};
|
||||
|
||||
/*@
|
||||
Ox.getObject <f> Returns the first object in an array where obj[key] is val
|
||||
> Ox.getObject([{a: 1, i: 0}, {a: 2, i: 1}, {a: 1, i: 2}], 'a', 2)
|
||||
{a: 2, i: 1}
|
||||
> Ox.getObject([{a: 1, i: 0}, {a: 2, i: 1}, {a: 1, i: 2}], 'a', 1)
|
||||
{a: 1, i: 0}
|
||||
> Ox.getObject([{a: 1, i: 0}, {a: 2, i: 1}, {a: 1, i: 2}], 'a', 0)
|
||||
null
|
||||
@*/
|
||||
Ox.getObject = function(arr, key, val) {
|
||||
var ret = null;
|
||||
Ox.forEach(arr, function(obj) {
|
||||
if (obj[key] === val) {
|
||||
ret = obj;
|
||||
return false;
|
||||
}
|
||||
return Ox.indexOf(arr, function(obj) {
|
||||
return obj.id === id;
|
||||
});
|
||||
return ret;
|
||||
};
|
||||
|
||||
/*@
|
||||
Ox.getObjectById <f> Returns the first object in an array with a given id
|
||||
> Ox.getObjectById([{id: 'foo', str: 'Foo'}, {id: 'bar', str: 'Bar'}], 'foo')
|
||||
{id: "foo", str: "Foo"}
|
||||
> 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) {
|
||||
// FIXME: shouldn't this be merged into Ox.getObject?
|
||||
return Ox.getObject(arr, 'id', id);
|
||||
var index = Ox.getIndexById(arr, id);
|
||||
return index > -1 ? arr[index] : null;
|
||||
};
|
||||
|
||||
/*@
|
||||
|
@ -309,6 +286,20 @@ Ox.getset = function(obj, args, callback, context) {
|
|||
return ret;
|
||||
}
|
||||
|
||||
/*@
|
||||
Ox.indexOf <f> <code>indexOf</code> with a test function
|
||||
> Ox.indexOf([1, 2, 3], function(val) { return val % 2 == 0; })
|
||||
1
|
||||
> Ox.indexOf('fooBar', function(val) { return val == val.toUpperCase(); })
|
||||
3
|
||||
@*/
|
||||
Ox.indexOf = function(col, fn) {
|
||||
var index = Ox.forEach(col, function(val) {
|
||||
fn(val) && Ox.break();
|
||||
});
|
||||
return index == col.length ? -1 : index;
|
||||
};
|
||||
|
||||
/*@
|
||||
Ox.isEmpty <f> Tests if a value is an empty array, object or string
|
||||
(value) -> <b> True if the value is an empty array, object or string
|
||||
|
@ -361,8 +352,8 @@ Ox.keys = function(obj) {
|
|||
|
||||
/*@
|
||||
Ox.last <f> Gets or sets the last element of an array
|
||||
Unlike <code>foobarbaz[foobarbaz.length - 1]</code>,
|
||||
<code>Ox.last(foobarbaz)</code> is short.
|
||||
Unlike <code>arrayWithALongName[arrayWithALongName.length - 1]</code>,
|
||||
<code>Ox.last(arrayWithALongName)</code> is short.
|
||||
<script>
|
||||
Ox.test.array = [1, 2, 3];
|
||||
</script>
|
||||
|
@ -372,6 +363,8 @@ Ox.last <f> Gets or sets the last element of an array
|
|||
[1, 2, 4]
|
||||
> Ox.test.array
|
||||
[1, 2, 4]
|
||||
> Ox.last('123')
|
||||
'3'
|
||||
@*/
|
||||
Ox.last = function(arr, val) {
|
||||
var ret;
|
||||
|
@ -449,14 +442,14 @@ Ox.makeObject <f> Takes an array and returns an object
|
|||
> (function() { return Ox.makeObject(arguments); }())
|
||||
{}
|
||||
@*/
|
||||
Ox.makeObject = function(obj) {
|
||||
var ret = {};
|
||||
if (Ox.isObject(obj[0])) {
|
||||
Ox.makeObject = function(arr) {
|
||||
var ret = {}, type = Ox.typeOf(arr[0]);
|
||||
if (type == 'object') {
|
||||
// ({foo: 'bar'})
|
||||
ret = obj[0];
|
||||
} else if (obj.length) {
|
||||
ret = arr[0];
|
||||
} else if (type == 'string') {
|
||||
// ('foo', 'bar')
|
||||
ret[obj[0]] = obj[1]
|
||||
ret[arr[0]] = arr[1];
|
||||
}
|
||||
return ret;
|
||||
};
|
||||
|
@ -506,7 +499,15 @@ Ox.max <f> Returns the maximum value of a collection
|
|||
3
|
||||
@*/
|
||||
Ox.max = function(col) {
|
||||
return Math.max.apply(Math, Ox.values(col));
|
||||
var ret, values = Ox.values(col);
|
||||
if (values.length < Ox.STACK_LENGTH) {
|
||||
ret = Math.max.apply(null, values)
|
||||
} else {
|
||||
ret = values.reduce(function(pre, val) {
|
||||
return Math.max(pre, val);
|
||||
}, -Infinity);
|
||||
}
|
||||
return ret;
|
||||
};
|
||||
|
||||
/*@
|
||||
|
@ -519,7 +520,15 @@ Ox.min <f> Returns the minimum value of a collection
|
|||
1
|
||||
@*/
|
||||
Ox.min = function(col) {
|
||||
return Math.min.apply(Math, Ox.values(col));
|
||||
var ret, values = Ox.values(col);
|
||||
if (values.length < Ox.STACK_LENGTH) {
|
||||
ret = Math.min.apply(null, values)
|
||||
} else {
|
||||
ret = values.reduce(function(pre, val) {
|
||||
return Math.min(pre, val);
|
||||
}, Infinity);
|
||||
}
|
||||
return ret;
|
||||
};
|
||||
|
||||
/*@
|
||||
|
@ -595,7 +604,16 @@ Ox.shuffle = function(col) {
|
|||
};
|
||||
|
||||
/*@
|
||||
Ox.some <f> Tests if one or more elements of a collection satisfy a given condition
|
||||
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.some <f> Tests if one or more elements of a collection meet a given condition
|
||||
Unlike <code>[].some()</code>, <code>Ox.some()</code> works for arrays,
|
||||
objects and strings.
|
||||
> Ox.some([2, 1, 0], function(i, v) { return i == v; })
|
||||
|
@ -604,7 +622,7 @@ Ox.some <f> Tests if one or more elements of a collection satisfy a given condit
|
|||
true
|
||||
> Ox.some("foo", function(v) { return v == 'f'; })
|
||||
true
|
||||
> Ox.some([false, 0, null, '', void 0])
|
||||
> Ox.some([false, null, 0, '', void 0])
|
||||
false
|
||||
@*/
|
||||
Ox.some = function(obj, fn) {
|
||||
|
@ -670,7 +688,6 @@ Ox.sum = function(col) {
|
|||
|
||||
/*@
|
||||
Ox.toArray <f> Takes an array-like object and returns a true array
|
||||
Alias for <code>Array.prototype.slice.call</code>
|
||||
(value) -> <a> True array
|
||||
value <*> Array-like object
|
||||
> (function() { return Ox.toArray(arguments); }("foo", "bar"))
|
||||
|
@ -711,12 +728,18 @@ Ox.values <f> Returns the values of a collection
|
|||
[1, 3]
|
||||
@*/
|
||||
Ox.values = function(col) {
|
||||
// Ox.values(str) is identical to str.split('')
|
||||
var values = [];
|
||||
Ox.forEach(col, function(val) {
|
||||
values.push(val);
|
||||
});
|
||||
return values;
|
||||
var ret, type = Ox.typeOf(col);
|
||||
if (type == 'array') {
|
||||
ret = col;
|
||||
} else if (type == 'object') {
|
||||
ret = [];
|
||||
Ox.forEach(col, function(val) {
|
||||
ret.push(val);
|
||||
});
|
||||
} else if (type == 'string') {
|
||||
ret = col.split('');
|
||||
}
|
||||
return ret;
|
||||
};
|
||||
|
||||
/*@
|
||||
|
|
Loading…
Reference in a new issue