JavaScript count
Count the number of elements in a variable (usually an array)
1 2 3 4 56 7 8 9 1011 12 13 14 1516 17 18 19 2021 22 23 24 2526 27 28 29 3031 32 33 34 3536 37 38 39 40 | function count (mixed_var, mode) { // Count the number of elements in a variable (usually an array) // // version: 1008.1718 // discuss at: http://phpjs.org/functions/count // + original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) // + input by: Waldo Malqui Silva // + bugfixed by: Soren Hansen // + input by: merabi // + improved by: Brett Zamir (http://brett-zamir.me) // * example 1: count([[0,0],[0,-4]], 'COUNT_RECURSIVE'); // * returns 1: 6 // * example 2: count({'one' : [1,2,3,4,5]}, 'COUNT_RECURSIVE'); // * returns 2: 6 var key, cnt = 0; if (mixed_var === null){ return 0; } else if (mixed_var.constructor !== Array && mixed_var.constructor !== Object){ return 1; } if (mode === 'COUNT_RECURSIVE') { mode = 1; } if (mode != 1) { mode = 0; } for (key in mixed_var){ if (mixed_var.hasOwnProperty(key)) { cnt++; if ( mode==1 && mixed_var[key] && (mixed_var[key].constructor === Array || mixed_var[key].constructor === Object) ){ cnt += this.count(mixed_var[key], 1); } } } return cnt; } |
Examples
» Example 1
Running
1 | count([[0,0],[0,-4]], 'COUNT_RECURSIVE'); |
Should return
1 | 6 |
» Example 2
Running
1 | count({'one' : [1,2,3,4,5]}, 'COUNT_RECURSIVE'); |
Should return
1 | 6 |
Dependencies
No dependencies, you can use this function standalone.
Open syntax issues
php.js uses JsLint to help us keep our code consistent and prevent some common bugs.
Eventually we want all code to pass or at least take into consideration most fixes suggested by JsLint, following this JsLint configuration we’ve decided on.
Authors
Thanks to the following developers, you get to have count goodness in JavaScript.
this function has some issue:
when i want to count elements in array, this function counts the functions in it.
for example in jQuery's array (jQuery appends "remove" element in all array) this function counts the "remove" element too, and it is wrong!
i remade function:
function count( mixed_var, mode ) {
var key, cnt = 0;
if( mode == 'COUNT_RECURSIVE' ) mode = 1;
if( mode != 1 ) mode = 0;
for (key in mixed_var){
if(typeof(mixed_var[key]) != "function"){
cnt++;
if( mode==1 && mixed_var[key] && (mixed_var[key].constructor === Array || mixed_var[key].constructor === Object) ){
cnt += count(mixed_var[key], 1);
}
}
}
return cnt;
}
Small mistake, should off course be
if(mixed_var === null){
return 0;
} else if(mixed_var.constructor !== Array && mixed_var.constructor !== Object){
return 1;
}
count('teststring'); // Should return 1 according to the
It currently returns 10
Could be optimized by applying something like this in the beginning of the function:
if(mixed_var === null){
return 0;
} else if(mixed_var.constructor !== Array || mixed_var.constructor !== Object){
return 1;
}
@ Ates Goral: Great coding skills AND a sense of humor all in one person? Why you Should demand more gold medals ;)
But good idea anyway, let's program that the no.1 gets 2 medals in front of his name.
I take my demand for the extra gold medal back :) I realized that I could have just used a simple "not equal" instead of the XOR:
[CODE="Javascript"]
if (histogram[key] == 0 != mode_even)
[/CODE]
Here's count_chars():
[CODE="Javascript"]
function count_chars(str, mode) {
// * example 1: count_chars("Hello World!");
// * returns 1: {1:0, 2:0, 3:0, 4:0, 5:0, 6:0, 7:0, 8:0, 9:0, 10:0, 11:0, 12:0, 13:0, 14:0, 15:0, 16:0, 17:0, 18:0, 19:0, 20:0, 21:0, 22:0, 23:0, 24:0, 25:0, 26:0, 27:0, 28:0, 29:0, 30:0, 31:0, 32:1, 33:1, 34:0, 35:0, 36:0, 37:0, 38:0, 39:0, 40:0, 41:0, 42:0, 43:0, 44:0, 45:0, 46:0, 47:0, 48:0, 49:0, 50:0, 51:0, 52:0, 53:0, 54:0, 55:0, 56:0, 57:0, 58:0, 59:0, 60:0, 61:0, 62:0, 63:0, 64:0, 65:0, 66:0, 67:0, 68:0, 69:0, 70:0, 71:0, 72:1, 73:0, 74:0, 75:0, 76:0, 77:0, 78:0, 79:0, 80:0, 81:0, 82:0, 83:0, 84:0, 85:0, 86:0, 87:1, 88:0, 89:0, 90:0, 91:0, 92:0, 93:0, 94:0, 95:0, 96:0, 97:0, 98:0, 99:0, 100:1, 101:1, 102:0, 103:0, 104:0, 105:0, 106:0, 107:0, 108:3, 109:0, 110:0, 111:2, 112:0, 113:0, 114:1, 115:0, 116:0, 117:0, 118:0, 119:0, 120:0, 121:0, 122:0, 123:0, 124:0, 125:0, 126:0, 127:0, 128:0, 129:0, 130:0, 131:0, 132:0, 133:0, 134:0, 135:0, 136:0, 137:0, 138:0, 139:0, 140:0, 141:0, 142:0, 143:0, 144:0, 145:0, 146:0, 147:0, 148:0, 149:0, 150:0, 151:0, 152:0, 153:0, 154:0, 155:0, 156:0, 157:0, 158:0, 159:0, 160:0, 161:0, 162:0, 163:0, 164:0, 165:0, 166:0, 167:0, 168:0, 169:0, 170:0, 171:0, 172:0, 173:0, 174:0, 175:0, 176:0, 177:0, 178:0, 179:0, 180:0, 181:0, 182:0, 183:0, 184:0, 185:0, 186:0, 187:0, 188:0, 189:0, 190:0, 191:0, 192:0, 193:0, 194:0, 195:0, 196:0, 197:0, 198:0, 199:0, 200:0, 201:0, 202:0, 203:0, 204:0, 205:0, 206:0, 207:0, 208:0, 209:0, 210:0, 211:0, 212:0, 213:0, 214:0, 215:0, 216:0, 217:0, 218:0, 219:0, 220:0, 221:0, 222:0, 223:0, 224:0, 225:0, 226:0, 227:0, 228:0, 229:0, 230:0, 231:0, 232:0, 233:0, 234:0, 235:0, 236:0, 237:0, 238:0, 239:0, 240:0, 241:0, 242:0, 243:0, 244:0, 245:0, 246:0, 247:0, 248:0, 249:0, 250:0, 251:0, 252:0, 253:0, 254:0, 255:0}
// * example 2: count_chars("Hello World!", 0);
// * returns 2: {1:0, 2:0, 3:0, 4:0, 5:0, 6:0, 7:0, 8:0, 9:0, 10:0, 11:0, 12:0, 13:0, 14:0, 15:0, 16:0, 17:0, 18:0, 19:0, 20:0, 21:0, 22:0, 23:0, 24:0, 25:0, 26:0, 27:0, 28:0, 29:0, 30:0, 31:0, 32:1, 33:1, 34:0, 35:0, 36:0, 37:0, 38:0, 39:0, 40:0, 41:0, 42:0, 43:0, 44:0, 45:0, 46:0, 47:0, 48:0, 49:0, 50:0, 51:0, 52:0, 53:0, 54:0, 55:0, 56:0, 57:0, 58:0, 59:0, 60:0, 61:0, 62:0, 63:0, 64:0, 65:0, 66:0, 67:0, 68:0, 69:0, 70:0, 71:0, 72:1, 73:0, 74:0, 75:0, 76:0, 77:0, 78:0, 79:0, 80:0, 81:0, 82:0, 83:0, 84:0, 85:0, 86:0, 87:1, 88:0, 89:0, 90:0, 91:0, 92:0, 93:0, 94:0, 95:0, 96:0, 97:0, 98:0, 99:0, 100:1, 101:1, 102:0, 103:0, 104:0, 105:0, 106:0, 107:0, 108:3, 109:0, 110:0, 111:2, 112:0, 113:0, 114:1, 115:0, 116:0, 117:0, 118:0, 119:0, 120:0, 121:0, 122:0, 123:0, 124:0, 125:0, 126:0, 127:0, 128:0, 129:0, 130:0, 131:0, 132:0, 133:0, 134:0, 135:0, 136:0, 137:0, 138:0, 139:0, 140:0, 141:0, 142:0, 143:0, 144:0, 145:0, 146:0, 147:0, 148:0, 149:0, 150:0, 151:0, 152:0, 153:0, 154:0, 155:0, 156:0, 157:0, 158:0, 159:0, 160:0, 161:0, 162:0, 163:0, 164:0, 165:0, 166:0, 167:0, 168:0, 169:0, 170:0, 171:0, 172:0, 173:0, 174:0, 175:0, 176:0, 177:0, 178:0, 179:0, 180:0, 181:0, 182:0, 183:0, 184:0, 185:0, 186:0, 187:0, 188:0, 189:0, 190:0, 191:0, 192:0, 193:0, 194:0, 195:0, 196:0, 197:0, 198:0, 199:0, 200:0, 201:0, 202:0, 203:0, 204:0, 205:0, 206:0, 207:0, 208:0, 209:0, 210:0, 211:0, 212:0, 213:0, 214:0, 215:0, 216:0, 217:0, 218:0, 219:0, 220:0, 221:0, 222:0, 223:0, 224:0, 225:0, 226:0, 227:0, 228:0, 229:0, 230:0, 231:0, 232:0, 233:0, 234:0, 235:0, 236:0, 237:0, 238:0, 239:0, 240:0, 241:0, 242:0, 243:0, 244:0, 245:0, 246:0, 247:0, 248:0, 249:0, 250:0, 251:0, 252:0, 253:0, 254:0, 255:0}
// * example 3: count_chars("Hello World!", 1);
// * returns 3: {72:1, 101:1, 108:3, 111:2, 32:1, 87:1, 114:1, 100:1, 33:1}
// * example 4: count_chars("Hello World!", 2);
// * returns 4: {1:0, 2:0, 3:0, 4:0, 5:0, 6:0, 7:0, 8:0, 9:0, 10:0, 11:0, 12:0, 13:0, 14:0, 15:0, 16:0, 17:0, 18:0, 19:0, 20:0, 21:0, 22:0, 23:0, 24:0, 25:0, 26:0, 27:0, 28:0, 29:0, 30:0, 31:0, 34:0, 35:0, 36:0, 37:0, 38:0, 39:0, 40:0, 41:0, 42:0, 43:0, 44:0, 45:0, 46:0, 47:0, 48:0, 49:0, 50:0, 51:0, 52:0, 53:0, 54:0, 55:0, 56:0, 57:0, 58:0, 59:0, 60:0, 61:0, 62:0, 63:0, 64:0, 65:0, 66:0, 67:0, 68:0, 69:0, 70:0, 71:0, 73:0, 74:0, 75:0, 76:0, 77:0, 78:0, 79:0, 80:0, 81:0, 82:0, 83:0, 84:0, 85:0, 86:0, 88:0, 89:0, 90:0, 91:0, 92:0, 93:0, 94:0, 95:0, 96:0, 97:0, 98:0, 99:0, 102:0, 103:0, 104:0, 105:0, 106:0, 107:0, 109:0, 110:0, 112:0, 113:0, 115:0, 116:0, 117:0, 118:0, 119:0, 120:0, 121:0, 122:0, 123:0, 124:0, 125:0, 126:0, 127:0, 128:0, 129:0, 130:0, 131:0, 132:0, 133:0, 134:0, 135:0, 136:0, 137:0, 138:0, 139:0, 140:0, 141:0, 142:0, 143:0, 144:0, 145:0, 146:0, 147:0, 148:0, 149:0, 150:0, 151:0, 152:0, 153:0, 154:0, 155:0, 156:0, 157:0, 158:0, 159:0, 160:0, 161:0, 162:0, 163:0, 164:0, 165:0, 166:0, 167:0, 168:0, 169:0, 170:0, 171:0, 172:0, 173:0, 174:0, 175:0, 176:0, 177:0, 178:0, 179:0, 180:0, 181:0, 182:0, 183:0, 184:0, 185:0, 186:0, 187:0, 188:0, 189:0, 190:0, 191:0, 192:0, 193:0, 194:0, 195:0, 196:0, 197:0, 198:0, 199:0, 200:0, 201:0, 202:0, 203:0, 204:0, 205:0, 206:0, 207:0, 208:0, 209:0, 210:0, 211:0, 212:0, 213:0, 214:0, 215:0, 216:0, 217:0, 218:0, 219:0, 220:0, 221:0, 222:0, 223:0, 224:0, 225:0, 226:0, 227:0, 228:0, 229:0, 230:0, 231:0, 232:0, 233:0, 234:0, 235:0, 236:0, 237:0, 238:0, 239:0, 240:0, 241:0, 242:0, 243:0, 244:0, 245:0, 246:0, 247:0, 248:0, 249:0, 250:0, 251:0, 252:0, 253:0, 254:0, 255:0}
// * example 5: count_chars("Hello World!", 3);
// * returns 5: "Helo Wrd!"
// * example 6: count_chars("Hello World!", 4);
// * returns 6: "\x01\x02\x03\x04\x05\x06\x07\b \n\v\f\r\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGIJKLMNOPQRSTUVXYZ[\\]^_`abcfghijkmnpqstuvwxyz{|}~\x7F\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8A\x8B\x8C\x8D\x8E\x8F\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9A\x9B\x9C\x9D\x9E\x9F\xA0\xA1\xA2\xA3\xA4\xA5\xA6\xA7\xA8\xA9\xAA\xAB\xAC\xAD\xAE\xAF\xB0\xB1\xB2\xB3\xB4\xB5\xB6\xB7\xB8\xB9\xBA\xBB\xBC\xBD\xBE\xBF\xC0\xC1\xC2\xC3\xC4\xC5\xC6\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF\xD0\xD1\xD2\xD3\xD4\xD5\xD6\xD7\xD8\xD9\xDA\xDB\xDC\xDD\xDE\xDF\xE0\xE1\xE2\xE3\xE4\xE5\xE6\xE7\xE8\xE9\xEA\xEB\xEC\xED\xEE\xEF\xF0\xF1\xF2\xF3\xF4\xF5\xF6\xF7\xF8\xF9\xFA\xFB\xFC\xFD\xFE\xFF"
var histogram = new Object();
if (arguments.length == 1) {
mode = 0;
}
var mode_even = (mode & 1) == 0;
if (mode_even) {
for (var i = 1; i < 256; ++i) {
histogram[i] = 0;
}
}
for (var i = 0; i < str.length; ++i) {
var code = str.charCodeAt(i);
if (code in histogram) {
++histogram
;
} else {
histogram[code] = 1;
}
}
if (mode > 0) {
for (var key in histogram) {
if (histogram[key] == 0 ^ mode_even) {
delete histogram[key];
}
}
}
if (mode < 3) {
return histogram;
} else {
var ret = new Array();
for (var key in histogram) {
ret.push(String.fromCharCode(key));
}
return ret.join("");
}
}
I demand an extra gold medal for using a cryptic logical XOR inside an if statement ;)
Cool project, really.
Here's one of my conversions:
[CODE="Javascript"]
/*
* bool empty ( mixed $var )
*
* The following things are considered to be empty:
* "" (an empty string)
* 0 (0 as an integer)
* "0" (0 as a string)
* NULL
* FALSE
* array() (an empty array)
* var $var; (a variable declared, but without a value in a class)
*/
function empty(variable)
{
if( variable === "" || variable === 0 || variable === "0" || variable === null || variable === false || ( is_array(variable) && variable.length === 0 ) )
{
return true;
}
else
{
return false;
}
}
[/CODE]
Feel free to improve, edit, change the format, etc.


Brett Zamir
Apr 19th
For example:
function Class () { this.objMethod = function () {}; } Class.prototype.method = function () {}; var c = new Class(); for (var p in c) { // iterates "objMethod" but not "method" }So if jQuery's remove works like described at http://ejohn.org/blog/javascript-array-remove/ , you'll be ok there.
It is usually a good idea to define methods on the prototype because they will be shared across all inheriting objects, thus reducing memory load, while defining a method on each instance (as with "objMethod" above) creates a new function copy for each object instance and increases memory usage.
However, on regular arrays or object literals, the functions will be counted:
var a = {b: function () {}}; // We don't exclude 'b' because we don't know if someone meant it as data for their "associative array" var a = [function (){alert('a');}, function () {alert('b');}];Both of the above will still have the functions iterated by our version of count() since, again, some people want functions as data, as it is a particularly convenient feature of JS to be able to use them this way. Admittedly, for objects, it is less clear that the person intends them to be treated as data, but since our model in php.js is for object literals to be treated similarly to PHP associative arrays (as far as JS allows us at least), we have to allow for the possibility that someone intended a function there as data too.