Go Back   CodingForums.com > :: Client side development > JavaScript programming

Before you post, read our: Rules & Posting Guidelines

Reply
 
Thread Tools Rate Thread
Enjoy an ad free experience by logging in. Not a member yet? Register.
Old 10-07-2012, 05:57 PM   PM User | #1
esiason14
New Coder

 
Join Date: Jul 2005
Posts: 12
Thanks: 0
Thanked 0 Times in 0 Posts
esiason14 is an unknown quantity at this point
Loop through parsed JSON object, find values & count each occurence of selected field

I want to count the total number of occurrences of each value.

I start with JSON that looks like this:
Code:
{
"peeps":[
	{"id":"I0","name":"Bob","group":7,"school":"LSU"},
	{"id":"I1","name":"John","group":7,"school":"FSU"},
	{"id":"I2","name":"Tim","group":6,"school":"UNLV"},
	{"id":"I3","name":"Carl","group":3,"school":"UNC"},
	{"id":"I4","name":"John","group":6,"school":"LSU"},
	{"id":"I5","name":"Bob","group":5,"school":"LSU"},
	{"id":"I6","name":"John","group":6,"school":"UNC"},
	]
}
Through a drop-down box a user selects a field (name, group, school, etc). Based on that field, I want to call a function that returns the count of each unique occurrence. For example, if name is selected it would return an object or array with an ordinal index, the unique value, and total count. It must be an ordinal index.

Here is my current function:

Code:
// Pass JSON object and selected field name to count
function countFields(data,fieldName) {

	var Unique = []; // store unique values
	var Counts = []; // store occurences of each vbalue
	
    // Look at values in data.peeps
	for(var i in data.peeps)
	{
	    // Set index equal to value
	    var Index = data.peeps[i][fieldName];
	    
	    // Add value to Unique
	    Unique[Index] = data.peeps[i][fieldName];
	    
	    // Found the first occurence of a value
	    if(typeof(Counts[Index])=='undefined') {
	        Counts[Index]=1;
	    }
	    // Now we found another so increment count.
	    else {
	        Counts[Index]++;
	    }
	}
	
	// remove empty items
	Unique = Unique.filter(function(){ return true});
	Counts = Counts.filter(function(){ return true});
	
	var a=[];
	
	for(var i=0; i<Unique.length; i++)
	{
	    a.push({
			
			id: Unique[i],
			count: Counts[i]
		});
	}
	
	return a;
}
This seems to work if group is selected since it's an integer value.

console.dir(a) shows:
Object {id=7, count=2}
Object {id=6, count=3}
Object {id=3, count=1}
Object {id=1, count=1}

The problem is when I select any other non-integer field (name, etc). I only get "There are no child objects"
esiason14 is offline   Reply With Quote
Old 10-07-2012, 06:28 PM   PM User | #2
rnd me
Senior Coder

 
rnd me's Avatar
 
Join Date: Jun 2007
Location: Urbana
Posts: 3,455
Thanks: 9
Thanked 466 Times in 450 Posts
rnd me is a jewel in the roughrnd me is a jewel in the roughrnd me is a jewel in the rough
Quote:
//through a drop-down box a user selects a field (name, group, school, etc). Based on that field, I want to call a function that returns the count of each unique occurrence. For example, if name is selected it would return an object or array with an ordinal index, the unique value, and total count. It must be an ordinal index.

the ordinal index is the same as an array index on ordered arrays, aka all js arrays.
un-manipulated objects almost always preserve their key order, it's an informal agreement among implementations, so a simple flat object would work as well.


/need: unique value+count, sorted by count


Code:
data={
"peeps":[
	{"id":"I0","name":"Bob","group":7,"school":"LSU"},
	{"id":"I1","name":"John","group":7,"school":"FSU"},
	{"id":"I2","name":"Tim","group":6,"school":"UNLV"},
	{"id":"I3","name":"Carl","group":3,"school":"UNC"},
	{"id":"I4","name":"John","group":6,"school":"LSU"},
	{"id":"I5","name":"Bob","group":5,"school":"LSU"},
	{"id":"I6","name":"John","group":6,"school":"UNC"},
	]
};

function ob2arr   (ob) {
    var r = [],
    i = 0, z;
    for (z in ob) {
        if (ob.hasOwnProperty(z)) {
            r[i++] = [z, ob[z]];
        }
    }
    return r;
}//end ob2arr()  helper.


function countFields(data, fieldName) { //returns object, keys in sorted order:
  var used={};
   data.map(function(ob){ 
       used[ ob[fieldName] ] = used[ ob[fieldName] ] || 0; 
       used[ ob[fieldName] ]++;
   });
   ob2arr(used)
    .sort(function(a,b){return b[1]-a[1];})
    .map(function(a){delete used[a[0]]; used[a[0]]=a[1];});
  return used;
}


function countFields2(data, fieldName) { //returns 2-col array
  var used={};
   data.map(function(ob){ 
     used[ ob[fieldName] ] = used[ ob[fieldName] ] || 0; 
     used[ ob[fieldName] ]++;
   });
   return ob2arr(used)
     .sort(function(a,b){return b[1]-a[1];});
}

example usage and output of both:

Code:
countFields(data.peeps, "name")
/*
{
	"John": 3,
	"Bob": 2,
	"Tim": 1,
	"Carl": 1
}

*/

countFields2(data.peeps, "school")
/*
[
	[
		"LSU",
		3
	],
	[
		"UNC",
		2
	],
	[
		"FSU",
		1
	],
	[
		"UNLV",
		1
	]
]
*/
__________________
my site (updated 5/13)
STATS (2013/5) HTML5:90.2% MOB:14% IE7:0.5% IE8:8.6% IE9:9.8% IE10:10%

Last edited by rnd me; 10-07-2012 at 06:34 PM..
rnd me is offline   Reply With Quote
Old 10-08-2012, 02:49 PM   PM User | #3
esiason14
New Coder

 
Join Date: Jul 2005
Posts: 12
Thanks: 0
Thanked 0 Times in 0 Posts
esiason14 is an unknown quantity at this point
Thanks very much for taking the time to look at this. This worked perfectly and I appreciate it

Thanks
esiason14 is offline   Reply With Quote
Reply

Bookmarks

Tags
javascipt

Jump To Top of Thread


Thread Tools
Rate This Thread
Rate This Thread:

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT +1. The time now is 05:47 AM.


Advertisement
Log in to turn off these ads.