Diff code: array

Function:
Description: Creates an array.
Version A:
Version B:
array version 1array version 178
  1function array () {
  1function array () {
  2    // http://jsphp.co/jsphp/fn/view/array
  2    // http://jsphp.co/jsphp/fn/view/array
  3    // + original by: d3x
  3    // + original by: d3x
  4    // + improved by: Brett Zamir (http://brett-zamir.me)
  4    // + improved by: Brett Zamir (http://brett-zamir.me)
  5    // * example 1: array('Kevin', 'van', 'Zonneveld');
  5    // * example 1: array('Kevin', 'van', 'Zonneveld');
  6    // * returns 1: ['Kevin', 'van', 'Zonneveld']
  6    // * returns 1: ['Kevin', 'van', 'Zonneveld']
  7    // * example 2: ini_set('phpjs.return_phpjs_arrays', 'on');
  7    // * example 2: ini_set('phpjs.return_phpjs_arrays', 'on');
  8    // * example 2: var arr = array({0:2}, {a:41}, {2:3}).change_key_case('CASE_UPPER').keys();
  8    // * example 2: var arr = array({0:2}, {a:41}, {2:3}).change_key_case('CASE_UPPER').keys();
  9    // * returns 1: [0,'A',2]
  9    // * returns 1: [0,'A',2]
 10
 10
 11    var mainArgs = arguments, p = this.php_js = this.php_js || {},
 11    var mainArgs = arguments, p = this.php_js = this.php_js || {},
 12        _indexOf = function (value, from, strict) {
 12        _indexOf = function (value, from, strict) {
 13            for (var i = (from || 0), nonstrict = !strict, length=this.length; i < length; i++) {
 13            for (var i = (from || 0), nonstrict = !strict, length=this.length; i < length; i++) {
 14                if (this[i] === value || (nonstrict && this[i] == value)) {
 14                if (this[i] === value || (nonstrict && this[i] == value)) {
 15                    return i;
 15                    return i;
 16                }
 16                }
 17            }
 17            }
 18            return -1;
 18            return -1;
 19        };
 19        };
 20    // BEGIN REDUNDANT
 20    // BEGIN REDUNDANT
 21    if (!p.Relator) {
 21    if (!p.Relator) {
 22        p.Relator = function () {// Used this functional class for giving privacy to the class we are creating
 22        p.Relator = function () {// Used this functional class for giving privacy to the class we are creating
 23            // Code adapted from http://www.devpro.it/code/192.html
 23            // Code adapted from http://www.devpro.it/code/192.html
 24            // Relator explained at http://webreflection.blogspot.com/2008/07/javascript-relator-object-aka.html
 24            // Relator explained at http://webreflection.blogspot.com/2008/07/javascript-relator-object-aka.html
 25            // Its use as privacy technique described at http://webreflection.blogspot.com/2008/10/new-relator-object-plus-unshared.html
 25            // Its use as privacy technique described at http://webreflection.blogspot.com/2008/10/new-relator-object-plus-unshared.html
 26            // 1) At top of closure, put: var __ = Relator.$();
 26            // 1) At top of closure, put: var __ = Relator.$();
 27            // 2) In constructor, put: var _ = __.constructor(this);
 27            // 2) In constructor, put: var _ = __.constructor(this);
 28            // 3) At top of each prototype method, put: var _ = __.method(this);
 28            // 3) At top of each prototype method, put: var _ = __.method(this);
 29            // 4) Use like: _.privateVar = 5;
 29            // 4) Use like: _.privateVar = 5;
 30            function _indexOf (value) {
 30            function _indexOf (value) {
 31                for (var i = 0, length=this.length; i < length; i++) {
 31                for (var i = 0, length=this.length; i < length; i++) {
 32                    if (this[i] === value) {
 32                    if (this[i] === value) {
 33                        return i;
 33                        return i;
 34                    }
 34                    }
 35                }
 35                }
 36                return -1;
 36                return -1;
 37            }
 37            }
 38            function Relator () {
 38            function Relator () {
 39                var Stack = [], Array = [];
 39                var Stack = [], Array = [];
 40                if (!Stack.indexOf) {
 40                if (!Stack.indexOf) {
 41                    Stack.indexOf = _indexOf;
 41                    Stack.indexOf = _indexOf;
 42                }
 42                }
 43                return {
 43                return {
 44                    // create a new relator
 44                    // create a new relator
 45                    $ : function () {
 45                    $ : function () {
 46                        return Relator();
 46                        return Relator();
 47                    },
 47                    },
 48                    constructor : function (that) {
 48                    constructor : function (that) {
 49                        var i = Stack.indexOf(that);
 49                        var i = Stack.indexOf(that);
 50                        ~i ? Array[i] : Array[Stack.push(that) - 1] = {};
 50                        ~i ? Array[i] : Array[Stack.push(that) - 1] = {};
 51                        this.method(that).that = that;
 51                        this.method(that).that = that;
 52                        return this.method(that);
 52                        return this.method(that);
 53                    },
 53                    },
 54                    method : function (that) {
 54                    method : function (that) {
 55                        return Array[Stack.indexOf(that)];
 55                        return Array[Stack.indexOf(that)];
 56                    }
 56                    }
 57                };
 57                };
 58            }
 58            }
 59            return Relator();
 59            return Relator();
 60        }();
 60        }();
 61    }
 61    }
 62    // END REDUNDANT
 62    // END REDUNDANT
 63
 63
 64    if (p && p.ini && p.ini['phpjs.return_phpjs_arrays'].local_value.toLowerCase() === 'on') {
 64    if (p && p.ini && p.ini['phpjs.return_phpjs_arrays'].local_value.toLowerCase() === 'on') {
 65        if (!p.PHPJS_Array) {
 65        if (!p.PHPJS_Array) {
 66            // We keep this Relator outside the class in case adding prototype methods below
 66            // We keep this Relator outside the class in case adding prototype methods below
 67            // Prototype methods added elsewhere can also use this ArrayRelator to share these "pseudo-global mostly-private" variables
 67            // Prototype methods added elsewhere can also use this ArrayRelator to share these "pseudo-global mostly-private" variables
 68            var __ = p.ArrayRelator = p.ArrayRelator || p.Relator.$();
 68            var __ = p.ArrayRelator = p.ArrayRelator || p.Relator.$();
 69            // We could instead allow arguments of {key:XX, value:YY} but even more cumbersome to write
 69            // We could instead allow arguments of {key:XX, value:YY} but even more cumbersome to write
 70            p.PHPJS_Array = function PHPJS_Array () {
 70            p.PHPJS_Array = function PHPJS_Array () {
 71                var _ = __.constructor(this), args = arguments;
 71                var _ = __.constructor(this), args = arguments;
 72                args = (args.length === 1 && args[0] && typeof args[0] === 'object' &&
 72                args = (args.length === 1 && args[0] && typeof args[0] === 'object' &&
 73                        args[0].length && !args[0].propertyIsEnumerable('length')) ? args[0] : args; // If first and only arg is an array, use that (Don't depend on this)
 73                        args[0].length && !args[0].propertyIsEnumerable('length')) ? args[0] : args; // If first and only arg is an array, use that (Don't depend on this)
 74                if (!_.objectChain) {
 74                if (!_.objectChain) {
 75                    _.objectChain = args;
 75                    _.objectChain = args;
 76                    _.object = {};
 76                    _.object = {};
 77                    _.keys = [];
 77                    _.keys = [];
 78                    _.values = [];
 78                    _.values = [];
 79                }
 79                }
 80                for (var i=0, argl = args.length; i < argl; i++) {
 80                for (var i=0, argl = args.length; i < argl; i++) {
 81                    for (var p in args[i]) {
 81                    for (var p in args[i]) {
 82                        // Allow for access by key; use of private members to store sequence allows these to be iterated via for...in (but for read-only use, with hasOwnProperty or function filtering to avoid prototype methods, and per ES, potentially out of order)
 82                        // Allow for access by key; use of private members to store sequence allows these to be iterated via for...in (but for read-only use, with hasOwnProperty or function filtering to avoid prototype methods, and per ES, potentially out of order)
 83                        this[p] = _.object[p] = args[i][p];
 83                        this[p] = _.object[p] = args[i][p];
 84                        // Allow for easier access by prototype methods
 84                        // Allow for easier access by prototype methods
 85                        _.keys[_.keys.length] = p;
 85                        _.keys[_.keys.length] = p;
 86                        _.values[_.values.length] = args[i][p];
 86                        _.values[_.values.length] = args[i][p];
 87                        break;
 87                        break;
 88                    }
 88                    }
 89                }
 89                }
 90            };
 90            };
 91            var e = p.PHPJS_Array.prototype, that = this;
 91            var e = p.PHPJS_Array.prototype, that = this;
 92            e.change_key_case = function (cs) {var _ = __.method(this);
 92            e.change_key_case = function (cs) {var _ = __.method(this);
 93                var case_fn = (!cs || cs === 'CASE_LOWER') ? 'toLowerCase' : 'toUpperCase';
 93                var case_fn = (!cs || cs === 'CASE_LOWER') ? 'toLowerCase' : 'toUpperCase';
 94                for (var i=0, kl = _.keys.length; i < kl; i++) {
 94                for (var i=0, kl = _.keys.length; i < kl; i++) {
 95                    var oldkey = _.keys[i],
 95                    var oldkey = _.keys[i],
 96                        newkey = _.keys[i] = _.keys[i][case_fn]();
 96                        newkey = _.keys[i] = _.keys[i][case_fn]();
 97                    this[newkey] = _.object[newkey] = _.objectChain[i][newkey] = _.values[i]; // Fix: should we make a deep copy?
 97                    this[newkey] = _.object[newkey] = _.objectChain[i][newkey] = _.values[i]; // Fix: should we make a deep copy?
 98                    this[oldkey] = _.object[oldkey] = _.objectChain[i][oldkey] = null; // Break reference before deleting
 98                    this[oldkey] = _.object[oldkey] = _.objectChain[i][oldkey] = null; // Break reference before deleting
 99                    delete this[oldkey];
 99                    delete this[oldkey];
100                    delete _.object[oldkey];
100                    delete _.object[oldkey];
101                    delete _.objectChain[i][oldkey];
101                    delete _.objectChain[i][oldkey];
102                }
102                }
103                return this;
103                return this;
104            };
104            };
105            // Here we'll return actual arrays since most logical and practical for these functions to do this
105            // Here we'll return actual arrays since most logical and practical for these functions to do this
106            e.keys = function (search_value, argStrict) {var _ = __.method(this);
106            e.keys = function (search_value, argStrict) {var _ = __.method(this);
107                var pos, search = typeof search_value !== 'undefined',
107                var pos, search = typeof search_value !== 'undefined',
108                    tmp_arr = [],
108                    tmp_arr = [],
109                    strict = !!argStrict;
109                    strict = !!argStrict;
110                if (!search) {
110                if (!search) {
111                    return _.keys;
111                    return _.keys;
112                }
112                }
113                while ((pos = _indexOf(_.values, pos, strict)) !== -1) {
113                while ((pos = _indexOf(_.values, pos, strict)) !== -1) {
114                    tmp_arr[tmp_arr.length] = _.keys[pos];
114                    tmp_arr[tmp_arr.length] = _.keys[pos];
115                }
115                }
116                return tmp_arr;
116                return tmp_arr;
117            };
117            };
118            e.values = function () {var _ = __.method(this);
118            e.values = function () {var _ = __.method(this);
119                return _.values;
119                return _.values;
120            };
120            };
121            // Return non-object, non-array values, since most sensible
121            // Return non-object, non-array values, since most sensible
122            e.search = function (needle, argStrict) {var _ = __.method(this);
122            e.search = function (needle, argStrict) {var _ = __.method(this);
123                var strict = !!argStrict, haystack = _.values, i, vl, val;
123                var strict = !!argStrict, haystack = _.values, i, vl, val;
124                if (typeof needle === 'object' && needle.exec) { // Duck-type for RegExp
124                if (typeof needle === 'object' && needle.exec) { // Duck-type for RegExp
125                    if (!strict) { // Let's consider case sensitive searches as strict
125                    if (!strict) { // Let's consider case sensitive searches as strict
126                        var flags = 'i' + (needle.global ? 'g' : '') +
126                        var flags = 'i' + (needle.global ? 'g' : '') +
127                                    (needle.multiline ? 'm' : '') +
127                                    (needle.multiline ? 'm' : '') +
128                                    (needle.sticky ? 'y' : ''); // sticky is FF only
128                                    (needle.sticky ? 'y' : ''); // sticky is FF only
129                        needle = new RegExp(needle.source, flags);
129                        needle = new RegExp(needle.source, flags);
130                    }
130                    }
131                    for (i=0, vl = haystack.length; i < vl; i++) {
131                    for (i=0, vl = haystack.length; i < vl; i++) {
132                        val = haystack[i];
132                        val = haystack[i];
133                        if (needle.test(val)) {
133                        if (needle.test(val)) {
134                            return _.keys[i];
134                            return _.keys[i];
135                        }
135                        }
136                    }
136                    }
137                    return false;
137                    return false;
138                }
138                }
139                for (i=0, vl = haystack.length; i < vl; i++) {
139                for (i=0, vl = haystack.length; i < vl; i++) {
140                    val = haystack[i];
140                    val = haystack[i];
141                    if ((strict && val === needle) || (!strict && val == needle)) {
141                    if ((strict && val === needle) || (!strict && val == needle)) {
142                        return _.keys[i];
142                        return _.keys[i];
143                    }
143                    }
144                }
144                }
145                return false;
145                return false;
146            };
146            };
147            // Experimental functions
147            // Experimental functions
148            e.foreach = function (handler) {var _ = __.method(this);
148            e.foreach = function (handler) {var _ = __.method(this);
149                for (var i = 0, kl = _.keys.length; i < kl; i++) {
149                for (var i = 0, kl = _.keys.length; i < kl; i++) {
150                    if (handler.length === 1) {
150                    if (handler.length === 1) {
151                        handler(_.values[i]); // only pass the value
151                        handler(_.values[i]); // only pass the value
152                    }
152                    }
153                    else {
153                    else {
154                        handler(_.keys[i], _.values[i]);
154                        handler(_.keys[i], _.values[i]);
155                    }
155                    }
156                }
156                }
157                return this;
157                return this;
158            };
158            };
159            e.list = function () {var _ = __.method(this);
159            e.list = function () {var _ = __.method(this);
160                for (var i = 0, argl = arguments.length; i < argl; i++) {
160                for (var i = 0, argl = arguments.length; i < argl; i++) {
161                    var key = _.keys[i];
161                    var key = _.keys[i];
162                    if (key && key.length === parseInt(key).toString().length && // Key represents an int
162                    if (key && key.length === parseInt(key).toString().length && // Key represents an int
163                        parseInt(key) < argl) { // Key does not exceed arguments
163                        parseInt(key) < argl) { // Key does not exceed arguments
164                        that.window[arguments[key]] = _.values[key];
164                        that.window[arguments[key]] = _.values[key];
165                    }
165                    }
166                }
166                }
167                return this;
167                return this;
168            };
168            };
169            // Parallel functionality and naming of built-in JavaScript array methods
169            // Parallel functionality and naming of built-in JavaScript array methods
170            e.forEach = function (handler) {var _ = __.method(this);
170            e.forEach = function (handler) {var _ = __.method(this);
171                for (var i = 0, kl = _.keys.length; i < kl; i++) {
171                for (var i = 0, kl = _.keys.length; i < kl; i++) {
172                    handler(_.values[i], _.keys[i], this);
172                    handler(_.values[i], _.keys[i], this);
173                }
173                }
174                return this;
174                return this;
175            };
175            };
176            // Our own custom convenience functions
176            // Our own custom convenience functions
177            e.$object = function () {var _ = __.method(this);
177            e.$object = function () {var _ = __.method(this);
178                return _.object;
178                return _.object;
179            };
179            };
180            e.$objectChain = function () {var _ = __.method(this);
180            e.$objectChain = function () {var _ = __.method(this);
181                return _.objectChain;
181                return _.objectChain;
182            };
182            };
183        }
183        }
184        function PHPJS_Array() {}
184        function PHPJS_Array() {}
185        PHPJS_Array.prototype = p.PHPJS_Array.prototype;
185        PHPJS_Array.prototype = p.PHPJS_Array.prototype;
186        var arrInst = new PHPJS_Array();
186        var arrInst = new PHPJS_Array();
187        p.PHPJS_Array.apply(arrInst, mainArgs);
187        p.PHPJS_Array.apply(arrInst, mainArgs);
188        return arrInst;
188        return arrInst;
189    }
189    }
190    return Array.prototype.slice.call(mainArgs);
190    return Array.prototype.slice.call(mainArgs);
191}
191}