diff --git a/assets/collection/collection.js b/assets/collection/collection.js
index 714859a..a59d5cb 100644
--- a/assets/collection/collection.js
+++ b/assets/collection/collection.js
@@ -2,7 +2,7 @@
/**
* в разработке
*/
-kit.PluginManager.register('Collection',function(module, exports, require, global) {
+kit.PluginManager.register('Collection', function(module, exports, require, global) {
var support = require('support');
var valueEx = support.valueEx;
@@ -16,31 +16,83 @@ kit.PluginManager.register('Collection',function(module, exports, require, globa
}
return new Collection([]);
}
+
+ function setLastIndex(key){
+ var n = Number(key);
+ if (support.arr.isKey(key) && n > this.lastIndex) {
+ this.lastIndex = n;
+ }
+ return this.lastIndex;
+ }
+ function actualParams() {
+ var index;
+ this.length = this.__keys.length;
+ this.lastIndex = 0;
+ for(index in this.__keys) {
+ setLastIndex.call(this, this.__keys[index]);
+ }
+ }
/**
* @class Collection
* @memberOf kit
*/
var Collection = function (data = []) {
this.data = data;
- if(data instanceof NodeList) {
- this.type = 'NodeList';
- }
- else if(Array.isArray(data)) {
- this.type = 'Array';
+ 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';
+ }
}
else {
- this.type = 'Array';
+ this.type = 'array';
this.data = [data];
- this.type = undefined;
console.warn('collection: not support data' + typeof data);
}
+ var key;
+ this.lastIndex = 0;
+ this.length = 0;
+ this.__keys = [];
+ this.__values = [];
+ for(key in this.data) {
+ if(!this.data.hasOwnProperty(key)) continue;
+ setLastIndex.call(this, key);
+ this.length = this.__keys.push(support.arr.isKey(key)?Number(key):(''+key));
+ this.__values.push(this.data[key]);
+ }
};
Collection.prototype.all = function () {
- return this.data;
+ 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.push(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.all());
+ };
+ Collection.prototype.has = function (key) {
+ return this.data.hasOwnProperty(key) && this.__keys.includes(support.arr.isKey(key)?Number(key):(''+key));
+ };
+ Collection.prototype.indexKey = function (key) {
+ return this.__keys.indexOf(key);
};
/**
* @param key
@@ -48,7 +100,14 @@ kit.PluginManager.register('Collection',function(module, exports, require, globa
* @return {kit.Collection}
*/
Collection.prototype.set = Collection.prototype.put = function (key, value) {
- this.data[key] = value;
+ var index = -1;
+ if(this.has(key)) {
+ this.data[key] = this.__values[index = this.indexKey(key)] = value;
+ return this;
+ }
+ this.length = this.__keys.push(support.arr.isKey(key)?Number(key):(''+key));
+ this.data[key] = this.__values[this.length-1] = value;
+ setLastIndex.call(this, key);
return this;
};
/**
@@ -56,24 +115,18 @@ kit.PluginManager.register('Collection',function(module, exports, require, globa
* @return {kit.Collection}
*/
Collection.prototype.push = function (value) {
- if(this.type === 'Array') {
- this.data.push(value);
- return this;
- }
- this.data[support.uniqueId(8)] = value;
+ this.set(this.lastIndex + 1, value);
return this;
};
Collection.prototype.get = function (key, defValue = undefined) {
- if(this.data.hasOwnProperty(key)) {
+ if(this.has(key)) {
return this.data[key];
}
return defValue;
};
- Collection.prototype.has = function (key) {
- return this.data.hasOwnProperty(key);
- };
+
Collection.prototype.count = function () {
- return Object.keys(this.data).length;
+ return this.__keys.length;
};
Collection.prototype.isEmpty = function () {
return this.count() === 0;
@@ -114,13 +167,11 @@ kit.PluginManager.register('Collection',function(module, exports, require, globa
* @return {kit.Collection}
*/
Collection.prototype.eachReverse = function (callback = true) {
- var BreakException = {}, keys, i, key;
+ var BreakException = {}, i;
try {
- keys = Object.keys(this.data);
- if(keys.length)
- for (i = keys.length - 1; i >= 0; i--) {
- key = keys[i];
- if(valueEx(callback, this.data[key], key, this.data) === false) {
+ 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) {
throw BreakException;
}
}
@@ -189,26 +240,75 @@ kit.PluginManager.register('Collection',function(module, exports, require, globa
});
return res;
};
+
+ /**
+ * Method removes an item from the collection by its key
+ * @param key
+ * @return {kit.Collection}
+ */
Collection.prototype.forget = function (key) {
- key = '' + valueEx(key);
+ key = valueEx(key);
if(!this.has(key)) {
return this;
}
- switch (this.type) {
- case 'Array':
- case 'object':
- delete this.data[key];
- break;
- case 'NodeList':
- var newCollection = this.filter(function (v, k, arr) {
- return key !== Number(k).toString();
- });
- this.data = newCollection.data;
- break;
- default:
- }
+ var index = this.indexKey(key);
+ this.__keys.splice(index, 1);
+ this.__values.splice(index, 1);
+ actualParams.call(this);
+ delete this.data[key];
return this;
};
+ /**
+ * Method removes and returns an item from the collection by its key
+ * @param key
+ * @param defValue
+ * @return {kit.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);
+ actualParams.call(this);
+ delete this.data[key];
+ return value;
+ };
+ /**
+ * Method removes and returns the last item from the collection
+ */
+ Collection.prototype.pop = function(){
+ var index = this.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);
+ actualParams.call(this);
+ 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);
+ actualParams.call(this);
+ delete this.data[key];
+ return value;
+ };
/**
* @return {kit.Collection}
*/
@@ -218,12 +318,16 @@ kit.PluginManager.register('Collection',function(module, exports, require, globa
/**
* @return {kit.Collection}
*/
- Collection.prototype.dump = Collection.prototype.dd = function () {
+ Collection.prototype.dump = function () {
console.log('Collection', this.data);
return this;
};
+ Collection.prototype.dd = function () {
+ this.dump();
+ debugger;
+ return this;
+ };
+
return module.exports = Collection;
-});
-
-
+});
\ No newline at end of file
diff --git a/assets/support/support.js b/assets/support/support.js
index 18f6c0d..87375b7 100644
--- a/assets/support/support.js
+++ b/assets/support/support.js
@@ -7,6 +7,12 @@ __PluginManager__.register('support', function(module, exports, require, global)
return str[0].toUpperCase() + str.slice(1);
}
};
+ var arr = {
+ isKey: function (key) {
+ var n = Number(key);
+ return isInteger(n) && (''+n === ''+key);
+ }
+ };
function uniqueId (length = 32, firstLetter = true) {
var idStr = '';
if(length < 1) return idStr;
@@ -39,14 +45,35 @@ __PluginManager__.register('support', function(module, exports, require, global)
val === 0 ||
val === false;
}
+ function typeOf(value) {
+ return typeof value;
+ }
+ function isObject(value) {
+ return typeOf(value) === 'object' ? value !== null : typeof value === 'function';
+ }
+ function isNumber(value) {
+ return !Number.isNaN(value) && isFinite(value) && typeof value === 'number';
+ }
+ function isInteger(value) {
+ return isNumber(value) && (value % 1) === 0;
+ }
+ function isFloat(value) {
+ return isNumber(value);
+ }
/**
* @memberOf kit
*/
var support = {
str: str,
+ arr: arr,
uniqueId,
valueEx,
- empty
+ empty,
+ isNumber,
+ typeOf,
+ isObject,
+ isInteger,
+ isFloat,
};
return module.exports = support;
diff --git a/tests/kit.Collection.php b/tests/kit.Collection.php
index 7aa51a2..bc8ff2c 100644
--- a/tests/kit.Collection.php
+++ b/tests/kit.Collection.php
@@ -3,8 +3,8 @@
+print_r('by php collection: ');
$x = [];
-
$x[10] = 10;
$x[1] = 1;
print_r($x);
@@ -14,7 +14,17 @@ print_r($x);