Use PHP functions in JavaScript

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;
}
external links: original PHP docs | raw js source

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.

Comments

Add Comment
Use:
[CODE]
your_stuff('here');
[/CODE]
for proper code formatting
By submitting code here you are allowing us to use it in php.js hence dual licensing it under the MIT and GPL licenses

Gravatar
Brett Zamir
Apr 19th Permalink

q  @merabi: Thanks for your input on this. We really do need to go through our functions and do more for...in filtering. I have made a change at http://github.com/kvz/phpjs/commit/d7a15ad7c41914bdfdf56e5db4b0ffebd7dfaecb , but note that I have tested for hasOwnProperty instead of excluding functions as in your version. This is because one may sometimes wish to deliberately pass around functions as data. By checking against hasOwnProperty, we exclude functions (and properties) which are defined on the prototype (and less likely to be intended as data), but not those on the specific object instance.

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.

Gravatar
merabi
Apr 18th Permalink

q  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;
}

Gravatar
Brett Zamir
30 Apr '09 Permalink

q  Fixed in SVN, thanks!

Gravatar
Soren Hansen
28 Apr '09 Permalink

q  Small mistake, should off course be

if(mixed_var === null){ 
return 0; 
} else if(mixed_var.constructor !== Array && mixed_var.constructor !== Object){ 
return 1; 
}

Gravatar
Soren Hansen
28 Apr '09 Permalink

q  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;
}

Gravatar
Kevin van Zonneveld
22 Jan '08 Permalink

q  @ 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.

Gravatar
Ates Goral
22 Jan '08 Permalink

q  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]

Gravatar
Ates Goral
22 Jan '08 Permalink

q  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 &gt; 0) {
		for (var key in histogram) {
			if (histogram[key] == 0 ^ mode_even) {
				delete histogram[key];
			}
		}
	}
	
	if (mode &lt; 3) {
		return histogram;
	} else {
		var ret = new Array();
		
		for (var key in histogram) {
			ret.push(String.fromCharCode(key));
		}
		
		return ret.join(&quot;&quot;);
	}
}



I demand an extra gold medal for using a cryptic logical XOR inside an if statement ;)

Gravatar
Kevin van Zonneveld
10 Jan '08 Permalink

q  @ Philippe Baumann: Great contribution. I'll add it right away, thanks alot!

Gravatar
Philippe Baumann
9 Jan '08 Permalink

q  Cool project, really.

Here's one of my conversions:
[CODE=&quot;Javascript&quot;]
/*
* bool empty ( mixed $var )
*
* The following things are considered to be empty:
* &quot;&quot; (an empty string)
* 0 (0 as an integer)
* &quot;0&quot; (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 === &quot;&quot; || variable === 0 || variable === &quot;0&quot; || variable === null || variable === false || ( is_array(variable) &amp;&amp; variable.length === 0 ) )
{
return true;
}
else
{
return false;
}
}
[/CODE]
Feel free to improve, edit, change the format, etc.


Contribute a New function