mirror of
https://bitbucket.org/bellord13/kit.git
synced 2026-11-13 19:06:11 +03:00
fix
This commit is contained in:
@@ -0,0 +1,460 @@
|
||||
/** @module Collection */
|
||||
__PluginManager__.register('Collection', function(require, exports, module, global) {
|
||||
|
||||
var support = require('support');
|
||||
var valueEx = support.valueEx;
|
||||
|
||||
function filter(value, key, arr) {
|
||||
return !support.empty(value);
|
||||
}
|
||||
|
||||
function safeArrayKey(key){
|
||||
return support.arr.isKey(key)?Number(key):(''+key);
|
||||
}
|
||||
/**
|
||||
* @param type
|
||||
* @return {Collection}
|
||||
*/
|
||||
function getSimilarInstance(type) {
|
||||
if(type === 'object') {
|
||||
return new Collection({});
|
||||
}
|
||||
return new Collection([]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @class Collection
|
||||
* @property length
|
||||
* @memberOf {kit}
|
||||
*/
|
||||
var Collection = function (data = []) {
|
||||
var self = this;
|
||||
this.data = data;
|
||||
|
||||
support.definePropertyGet(this, 'length', function () {
|
||||
return self.__keys.length;
|
||||
});
|
||||
|
||||
if(data instanceof Collection) {
|
||||
this.__type = data.__type;
|
||||
this.__keys = data.__keys;
|
||||
this.__values = data.__values;
|
||||
return;
|
||||
}
|
||||
|
||||
if(Array.isArray(data)) {
|
||||
this.__type = 'array'; // []
|
||||
}
|
||||
else if(typeof data === 'object') {
|
||||
this.__type = 'object'; // {}
|
||||
if(data.hasOwnProperty('length') && !Object.keys(data).includes('length')) {
|
||||
this.__type = 'arrayObject'; // args
|
||||
}
|
||||
}
|
||||
else {
|
||||
this.__type = 'array';
|
||||
this.data = [data];
|
||||
console.warn('collection: not support data' + typeof data);
|
||||
}
|
||||
var key;
|
||||
this.__keys = [];
|
||||
this.__values = [];
|
||||
for(key in this.data) {
|
||||
if(!this.data.hasOwnProperty(key)) continue;
|
||||
this.__keys.push(safeArrayKey(key));
|
||||
this.__values.push(this.data[key]);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
Collection.prototype.__getLastIndex = function () {
|
||||
var lastIndex = -1, n = 0, index;
|
||||
for(index in this.__keys) {
|
||||
n = this.__keys[index];
|
||||
if (support.isNumber(n) && n > lastIndex) {
|
||||
lastIndex = n;
|
||||
}
|
||||
}
|
||||
return lastIndex;
|
||||
};
|
||||
Collection.prototype.all = function () {
|
||||
if(this.__type === 'array' || this.__type === 'arrayObject') {
|
||||
return this.toArray();
|
||||
}
|
||||
return this.toObject();
|
||||
};
|
||||
Collection.prototype.toArray = function () {
|
||||
var index, arr = [];
|
||||
for(index in this.__keys) {
|
||||
arr[this.__keys[index]] = this.__values[index];
|
||||
}
|
||||
return arr;
|
||||
};
|
||||
Collection.prototype.toObject = function () {
|
||||
var index, ob = {};
|
||||
for(index in this.__keys) {
|
||||
ob[this.__keys[index]] = this.__values[index];
|
||||
}
|
||||
return ob;
|
||||
};
|
||||
Collection.prototype.serialize = function () {
|
||||
return JSON.stringify(this.toObject());
|
||||
};
|
||||
Collection.prototype.serializeArray = function () {
|
||||
return JSON.stringify(this.toArray());
|
||||
};
|
||||
Collection.prototype.has = function (key) {
|
||||
return this.__keys.includes(safeArrayKey(key));
|
||||
};
|
||||
Collection.prototype.indexKey = function (key) {
|
||||
return this.__keys.indexOf(safeArrayKey(key));
|
||||
};
|
||||
/**
|
||||
* @param key
|
||||
* @param value
|
||||
* @return {Collection}
|
||||
*/
|
||||
Collection.prototype.add = Collection.prototype.set = Collection.prototype.put = function (key, value) {
|
||||
var index = -1;
|
||||
if(this.has(key)) {
|
||||
this.data[key] = this.__values[index = this.indexKey(key)] = value;
|
||||
return this;
|
||||
}
|
||||
this.__keys.push(safeArrayKey(key));
|
||||
this.data[key] = this.__values[this.length-1] = value;
|
||||
return this;
|
||||
};
|
||||
/**
|
||||
* @param value
|
||||
* @return {Collection}
|
||||
*/
|
||||
Collection.prototype.push = function (value) {
|
||||
this.set(this.__getLastIndex() + 1, value);
|
||||
return this;
|
||||
};
|
||||
Collection.prototype.get = function (key, defValue = undefined) {
|
||||
if(this.has(key)) {
|
||||
return this.data[key];
|
||||
}
|
||||
return defValue;
|
||||
};
|
||||
|
||||
Collection.prototype.count = function () {
|
||||
return this.__keys.length;
|
||||
};
|
||||
Collection.prototype.isEmpty = function () {
|
||||
return this.count() === 0;
|
||||
};
|
||||
/**
|
||||
* возвращает новый экземпляр коллекции; не изменяет вызываемую коллекцию
|
||||
*
|
||||
* @param callback
|
||||
* @return {Collection}
|
||||
*/
|
||||
Collection.prototype.map = function (callback) {
|
||||
var res = getSimilarInstance(this.__type);
|
||||
var index, key, value;
|
||||
for(index in this.__keys) {
|
||||
key = this.__keys[index];
|
||||
value = this.__values[index];
|
||||
res.put(key, valueEx(callback, value, key, this.data));
|
||||
}
|
||||
return res;
|
||||
};
|
||||
/**
|
||||
* @param callback
|
||||
* @return {Collection}
|
||||
*/
|
||||
Collection.prototype.each = function (callback = true) {
|
||||
var i;
|
||||
if(this.__keys.length)
|
||||
for (i = 0; i < this.__keys.length; i++) {
|
||||
if(valueEx(callback, this.__values[i], this.__keys[i], this.data) === false) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return this;
|
||||
};
|
||||
/**
|
||||
* @param callback
|
||||
* @return {Collection}
|
||||
*/
|
||||
Collection.prototype.eachReverse = function (callback = true) {
|
||||
var i;
|
||||
if(this.__keys.length)
|
||||
for (i = this.__keys.length - 1; i >= 0; i--) {
|
||||
if(valueEx(callback, this.__values[i], this.__keys[i], this.data) === false) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return this;
|
||||
};
|
||||
/**
|
||||
* @param callback
|
||||
* @return {Collection}
|
||||
*/
|
||||
Collection.prototype.filter = function (callback = filter) {
|
||||
var res = getSimilarInstance(this.__type);
|
||||
this.each(function (value, key, arr) {
|
||||
if(!!valueEx(callback, value, key, arr)) {
|
||||
res.put(key, value);
|
||||
}
|
||||
});
|
||||
return res;
|
||||
};
|
||||
|
||||
/**
|
||||
* Метод возвращает все элементы коллекции, кроме тех у кого ключи соответствуют заданным
|
||||
* @param keys
|
||||
* @return {Collection}
|
||||
*/
|
||||
Collection.prototype.except = function (keys) {
|
||||
var __keys = [], iKey;
|
||||
|
||||
if(!Array.isArray(keys)) {
|
||||
keys = [keys];
|
||||
}
|
||||
for(iKey in keys) {
|
||||
__keys.push(safeArrayKey(keys[iKey]));
|
||||
}
|
||||
|
||||
return this.filter(function (value, key) {
|
||||
return !__keys.includes(key);
|
||||
});
|
||||
};
|
||||
/**
|
||||
* Метод возвращает элементы коллекции с заданными ключами
|
||||
* @param keys
|
||||
* @return {Collection}
|
||||
*/
|
||||
Collection.prototype.only = function (keys) {
|
||||
var __keys = [], iKey;
|
||||
|
||||
if(!Array.isArray(keys)) {
|
||||
keys = [keys];
|
||||
}
|
||||
for(iKey in keys) {
|
||||
__keys.push(safeArrayKey(keys[iKey]));
|
||||
}
|
||||
|
||||
return this.filter(function (value, key) {
|
||||
return __keys.includes(key);
|
||||
});
|
||||
};
|
||||
Collection.prototype.every = function (callback) {
|
||||
var res = true;
|
||||
this.each(function (value, key, arr) {
|
||||
res = res && !!valueEx(callback, value, key, arr);
|
||||
});
|
||||
return res;
|
||||
};
|
||||
Collection.prototype.first = function (callback = true) {
|
||||
var res = undefined;
|
||||
this.each(function (value, key, arr) {
|
||||
if(valueEx(callback, value, key, arr)) {
|
||||
res = value;
|
||||
return false;
|
||||
}
|
||||
});
|
||||
return res;
|
||||
};
|
||||
Collection.prototype.firstKey = function (callback = true) {
|
||||
var res = undefined;
|
||||
this.each(function (value, key, arr) {
|
||||
if(valueEx(callback, value, key, arr)) {
|
||||
res = key;
|
||||
return false;
|
||||
}
|
||||
});
|
||||
return res;
|
||||
};
|
||||
Collection.prototype.last = function (callback = true) {
|
||||
var res = undefined;
|
||||
this.eachReverse(function (value, key, arr) {
|
||||
if(valueEx(callback, value, key, arr)) {
|
||||
res = value;
|
||||
return false;
|
||||
}
|
||||
});
|
||||
return res;
|
||||
};
|
||||
Collection.prototype.lastKey = function (callback = true) {
|
||||
var res = undefined;
|
||||
this.eachReverse(function (value, key, arr) {
|
||||
if(valueEx(callback, value, key, arr)) {
|
||||
res = key;
|
||||
return false;
|
||||
}
|
||||
});
|
||||
return res;
|
||||
};
|
||||
|
||||
/**
|
||||
* Method removes/delete an item from the collection by its key
|
||||
* @param key
|
||||
* @return {Collection}
|
||||
*/
|
||||
Collection.prototype.forget = function (key) {
|
||||
key = valueEx(key);
|
||||
if(!this.has(key)) {
|
||||
return this;
|
||||
}
|
||||
var index = this.indexKey(key);
|
||||
this.__keys.splice(index, 1);
|
||||
this.__values.splice(index, 1);
|
||||
delete this.data[key];
|
||||
return this;
|
||||
};
|
||||
/**
|
||||
* Method removes and returns an item from the collection by its key
|
||||
* @param key
|
||||
* @param defValue
|
||||
* @return {Collection}
|
||||
*/
|
||||
Collection.prototype.pull = function (key, defValue = undefined) {
|
||||
key = valueEx(key);
|
||||
if(!this.has(key)) {
|
||||
return defValue;
|
||||
}
|
||||
var index = this.indexKey(key);
|
||||
var value = this.__values[index];
|
||||
this.__keys.splice(index, 1);
|
||||
this.__values.splice(index, 1);
|
||||
delete this.data[key];
|
||||
return value;
|
||||
};
|
||||
/**
|
||||
* Method removes and returns the last item from the collection
|
||||
*/
|
||||
Collection.prototype.pop = function(){
|
||||
var index = this.__keys.length - 1;
|
||||
if(index < 0) {
|
||||
return undefined;
|
||||
}
|
||||
var key = this.__keys[index];
|
||||
var value = this.__values[index];
|
||||
this.__keys.splice(index, 1);
|
||||
this.__values.splice(index, 1);
|
||||
delete this.data[key];
|
||||
return value;
|
||||
};
|
||||
/**
|
||||
* Method removes and returns the first item from the collection
|
||||
*/
|
||||
Collection.prototype.shift = function(){
|
||||
var index = 0;
|
||||
if(this.length <= 0) {
|
||||
return undefined;
|
||||
}
|
||||
var key = this.__keys[index];
|
||||
var value = this.__values[index];
|
||||
this.__keys.splice(index, 1);
|
||||
this.__values.splice(index, 1);
|
||||
delete this.data[key];
|
||||
return value;
|
||||
};
|
||||
/**
|
||||
* @return {Collection}
|
||||
*/
|
||||
Collection.prototype.keys = function () {
|
||||
return new Collection(Object.keys(this.data));
|
||||
};
|
||||
/**
|
||||
* @return {Collection}
|
||||
*/
|
||||
Collection.prototype.dump = function () {
|
||||
console.log('Collection', this.data);
|
||||
return this;
|
||||
};
|
||||
/**
|
||||
* @return {Collection}
|
||||
*/
|
||||
Collection.prototype.dd = function () {
|
||||
this.dump();
|
||||
debugger;
|
||||
return this;
|
||||
};
|
||||
/**
|
||||
* @return {Collection}
|
||||
*/
|
||||
Collection.prototype.eachCall = function (context, args1, args2) {
|
||||
var args = [], i;
|
||||
if(arguments.length > 1)
|
||||
for(i = 1; arguments.length - 1 >= i;i++) {
|
||||
args.push(arguments[i]);
|
||||
}
|
||||
|
||||
if(this.__keys.length)
|
||||
for (i = 0; i < this.__keys.length; i++) {
|
||||
if(typeof this.__values[i] === 'function' &&
|
||||
this.__values[i].apply(context, args) === false) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* аналог Array.includes
|
||||
*
|
||||
* @param searchElement
|
||||
* @param fromIndex
|
||||
* @return {boolean}
|
||||
*/
|
||||
Collection.prototype.includes = function(searchElement, fromIndex) {
|
||||
var len = this.__keys.length;
|
||||
if (len === 0) {
|
||||
return false;
|
||||
}
|
||||
var n = fromIndex | 0;
|
||||
var k = Math.max(n >= 0 ? n : len - Math.abs(n), 0);
|
||||
function sameValueZero(x, y) {
|
||||
return x === y || (typeof x === 'number' && typeof y === 'number' && isNaN(x) && isNaN(y));
|
||||
}
|
||||
while (k < len) {
|
||||
if (sameValueZero(this.__values[k], searchElement)) {
|
||||
return true;
|
||||
}
|
||||
k++;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
Collection.prototype.search = function(searchElement) {
|
||||
var len = this.__keys.length;
|
||||
if (len === 0) {
|
||||
return false;
|
||||
}
|
||||
var k = 0;
|
||||
function sameValueZero(x, y) {
|
||||
return x === y || (typeof x === 'number' && typeof y === 'number' && isNaN(x) && isNaN(y));
|
||||
}
|
||||
while (k < len) {
|
||||
if (sameValueZero(this.__values[k], searchElement)) {
|
||||
return this.__keys[k];
|
||||
}
|
||||
k++;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
/**
|
||||
* Метод извлекает все значения для данного ключа
|
||||
* ключи оставляет исходные
|
||||
* Значения в коллекци должны быть массиво подобные
|
||||
*
|
||||
* @param key
|
||||
* @return {Collection}
|
||||
*/
|
||||
Collection.prototype.pluck = function (key) {
|
||||
return this.map(function (value) {
|
||||
if(value instanceof Object && value.hasOwnProperty(key)){
|
||||
return value[key];
|
||||
}
|
||||
return undefined;
|
||||
});
|
||||
};
|
||||
return module.exports = Collection;
|
||||
});
|
||||
Reference in New Issue
Block a user