37,6 → 37,7 |
var _getKeys = _jsx_object.getKeys; |
var _hasOwnProperty = _jsx_object._hasOwnProperty; |
var _isArray = _jsx_object.isArray; |
var _isObject = _jsx_object.isObject; |
var _isNativeObject = _jsx_object.isNativeObject; |
|
/* Constant-like variables */ |
908,6 → 909,37 |
} |
}); |
|
/** |
* Returns the indexes of an array-like object as an {@link Array} |
* |
* @param {Array} a |
* @param {boolean} bStrict = false |
* If <code>true</code>, properties are only considered |
* indexes if they meet the definition in the ECMAScript |
* Language Specification, 5.1 Edition. The default is |
* <code>false</code> which considers all integers. |
* @return {Array} |
*/ |
function _getIndexes (a, bStrict) |
{ |
var keys = _getKeys(a); |
var result = []; |
for (var i = 0, len = keys.length; i < len; ++i) |
{ |
var key = keys[i]; |
|
if (key % 1 == 0) |
{ |
if (!bStrict || (key > -1 && key < _MAX_ARRAY_LENGTH - 1)) |
{ |
result.push(key); |
} |
} |
} |
|
return result; |
} |
|
return { |
/** |
* @memberOf jsx.array |
1064,6 → 1096,8 |
* or <code>false</code>. If it returns <code>true</code> |
* for the element of <code>a</code>, that element is |
* included in the resulting array, otherwise it is not. |
* A function that filters on property values can be created |
* with {@link createFilter()}. |
* @param {Array} a (optional) |
* Array which should be filtered. Is used instead of the |
* <code>Array</code> object the function is applied to. |
1077,7 → 1111,7 |
{ |
if (_isArray(fCallback)) |
{ |
var tmp = a; |
var tmp = fCallback; |
fCallback = a; |
a = tmp; |
} |
1093,7 → 1127,7 |
} |
} |
|
var len = this.length; |
var len = a.length; |
|
if (typeof fCallback != "function") |
{ |
1104,10 → 1138,10 |
|
for (var i = 0; i < len; i++) |
{ |
if (i in this) |
if (i in a) |
{ |
/* mozilla.org: in case fCallback mutates `this'(?) */ |
var val = this[i]; |
var val = a[i]; |
|
if (fCallback.call(a, val, i, this)) |
{ |
1120,20 → 1154,158 |
}, |
|
/** |
* Creates an {@link Array} from the own enumerable properties |
* of an object. |
* |
* @param {Object} obj |
* @param {Object} options |
* <table> |
* <thead> |
* <tr> |
* <th>Option</th> |
* <th>Type</th> |
* <th>Meaning</th> |
* </tr> |
* <thead> |
* <tbody> |
* <tr> |
* <th>preserveKeys</th> |
* <td><code>boolean</code></th> |
* <td>If <code>true</code>, the return value is an |
* <code>Array</code> of <code>Object</code>s |
* whose elements have properties <code>key</code> |
* and <code>value</code>, for the original object's |
* property names and associated values, respectively.<br> |
* The default is <code>false</code>, so that the |
* referred <code>Array</code> only contains the |
* original property values.</td> |
* </tr> |
* <tr> |
* <th>depth</th> |
* <td><code>number</code></th> |
* <td>If not equal to <code>0</code> and the original |
* property value is a reference to an object, that |
* object's properties are turned into an array as well, |
* using this method, so are its properties, and so on. |
* If less than <code>0</code>, recursion is performed |
* as deep as possible; if greater than <code>0</code>, |
* recursion is performed until the specified depth |
* is reached. The default is <code>0</code>. |
* <em>Note that recursion is limited by the maximum |
* stack size.</em></td> |
* </tr> |
* </tbody> |
* </table> |
* @return {Array[Object]} that can be filtered with {@link #filter()}. |
*/ |
fromObject: function jsx_array_fromObject (obj, options) { |
var keys = _getKeys(obj); |
var result = []; |
|
for (var i = 0, len = keys.length; i < len; ++i) |
{ |
var key = keys[i]; |
var value = obj[key]; |
|
var item = value; |
|
if (options) |
{ |
if (typeof options.depth != "undefined") |
{ |
options.depth = Math.floor(options.depth); |
|
if (options.depth != 0 && _isObject(value)) |
{ |
--options.depth; |
value = jsx_array_fromObject(value, options); |
} |
} |
|
if (options.preserveKeys) |
{ |
item = { |
key: key, |
value: value |
}; |
} |
} |
|
result.push(item); |
} |
|
return result; |
}, |
|
getIndexes: _getIndexes, |
|
/** |
* Returns a function that can be used for filtering an {@link Array} |
* by the property values of its elements. |
* |
* @param {Object} filter |
* Object whose property names are the elements' property |
* names, and whose property values are the element's property |
* values to compare against |
* @param {boolean} bStrict = false |
* If <code>true</code>, perform strict comparison. |
* @return {Function} |
* The filter function |
* @see jsx.array.filter |
* Object whose property names (keys) are compared agains |
* the elements' property names, and whose property values |
* (key values) are compared against the elements' |
* corresponding property values. A filter key value of |
* <code>NaN</code> applies to <code>NaN</code> element |
* property values even though <code>NaN</code> usually |
* does not compare equal to anything. |
* @param {Object} options |
* <table> |
* <thead> |
* <tr> |
* <th>Key</th> |
* <th>Type</th> |
* <th>Meaning</th> |
* </tr> |
* </thead> |
* <tbody> |
* <tr> |
* <th>compareStructure</th> |
* <td><code>boolean</code></td> |
* <td>If <code>true</code> and the filter key value |
* is an object, perform structural comparison. |
* If it or a subordered entity is an <code>Array</code> |
* instance, use its elements to filter for |
* items that have the same value or structure: |
* Otherwise, filter for elements' properties whose |
* value is a reference to an object with the specified |
* properties. Examples: |
* <ol> |
* <li><pre><code>jsx.array.filter(jsx.array.createFilter({foo: {bar: "baz"}), <var>a</var>);</code></pre> |
* filters the array-like object referred to by |
* <code><var>a</var></code> for elements whose |
* values are references to objects whose |
* <code>foo</code> property value is a reference |
* to an object whose <code>bar</code> property |
* value is <code>"baz"</code>.</li> |
* <li><pre><code>jsx.array.filter(jsx.array.createFilter({foo: [, "bar"]}), <var>a</var>);</code></pre> |
* filters the array-like object referred to by |
* <code><var>a</var></code> for elements whose |
* values are references to an object whose |
* <code>foo</code> property value is a reference |
* to an <code>Aarray</code> instance whose second |
* element is <code>"bar"</code>.</li> |
* </ol> |
* The default is <code>false</code>.</td> |
* </tr> |
* </tbody> |
* <tr> |
* <th>strict</th> |
* <td><code>boolean</code></td> |
* <td>If <code>true</code> and <var>compareStructure</var> |
* is <code>false</code>, perform strict comparison. |
* The default is <code>false</code>.</td> |
* </tr> |
* </tbody> |
* </table> |
* @return {Function} that takes the element as first and only |
* argument and returns <code>true</code> if the element meets |
* all specified filter criteria, <code>false</code> otherwise. |
* @see jsx.array.filter() |
*/ |
createFilter: function (filter, bStrict) { |
createFilter: function (filter, options) { |
var keys = _getKeys(filter); |
|
/** |
1141,24 → 1313,133 |
* @return {boolean} |
*/ |
return function (element) { |
for (var i = 0, len = keys.length; i < len; ++i) |
function _isNaN (value) |
{ |
var key = keys[i]; |
return (typeof value == "number" && isNaN(value)); |
} |
|
/** |
* @param item |
* @param filter |
*/ |
function _structureCompare (item, filter, bStrict) |
{ |
if (_isArray(filter)) |
{ |
if (!_isArray(item)) |
{ |
return false; |
} |
|
var filter_keys = _getIndexes(filter); |
for (var i = 0, len = filter_keys.length; i < len; ++i) |
{ |
var array_key = filter_keys[i]; |
var array_value = item[array_key]; |
var filter_value = filter[array_key]; |
|
if (_isObject(filter_value)) |
{ |
if (!_structureCompare(array_value, filter_value, bStrict)) |
{ |
return false; |
} |
} |
else |
{ |
if (bStrict) |
{ |
if (element[key] === filter[key]) |
if (array_value !== filter_value) |
{ |
return true; |
return false; |
} |
} |
else if (array_value != filter_value) |
{ |
return false; |
} |
} |
} |
} |
else if (_isObject(filter)) |
{ |
if (!_isObject(item)) |
{ |
return false; |
} |
|
filter_keys = _getKeys(filter); |
for (var i = 0, len = filter_keys.length; i < len; ++i) |
{ |
var object_key = filter_keys[i]; |
var object_value = item[object_key]; |
filter_value = filter[object_key]; |
|
if (_isObject(filter_value)) |
{ |
if (!_structureCompare(object_value, filter_value, bStrict)) |
{ |
return false; |
} |
} |
else |
{ |
if (element[key] == filter[key]) |
if (bStrict) |
{ |
if (object_value !== filter_value) |
{ |
return false; |
} |
} |
else if (object_value != filter_value) |
{ |
return false; |
} |
} |
} |
} |
|
return true; |
} |
|
for (var i = 0, len = keys.length; i < len; ++i) |
{ |
var key = keys[i]; |
var element_property_value = element[key]; |
var filter_key_value = filter[key]; |
|
if (_isNaN(filter_key_value) && |
!_isNaN(element_property_value)) |
{ |
return false; |
} |
|
if (options.compareStructure) |
{ |
if (!_structureCompare( |
element_property_value, filter_key_value, |
options && options.strict)) |
{ |
return false; |
} |
} |
else |
{ |
if (options && options.strict) |
{ |
if (element_property_value !== filter_key_value) |
{ |
return false; |
} |
} |
else if (element_property_value != filter_key_value) |
{ |
return false; |
} |
} |
} |
|
return true; |
}; |
}, |
|
1695,11 → 1976,6 |
* Returns a function that can be used for sorting an {@link Array}. |
* |
* @author (C) 2013 Thomas 'PointedEars' Lahn <js@PointedEars.de> |
*/ |
createComparator: (function () { |
var _isObject = _jsx_object.isObject; |
|
/** |
* @param {Array} aKeys |
* Array of keys that should be sorted by, in order. |
* A key may be a {@link string} value or a native object. |
1809,7 → 2085,7 |
* </table> |
* @return {Function} |
*/ |
function _createComparator (aKeys, options) |
createComparator: function (aKeys, options) |
{ |
if (aKeys == null || !_isArray(aKeys)) |
{ |
1898,9 → 2174,6 |
} |
}; |
} |
|
return _createComparator; |
}()) |
}; |
}()); |
|