Hello and welcome to our community! Is this your first visit?
Register
Enjoy an ad free experience by logging in. Not a member yet? Register.
Results 1 to 3 of 3
  1. #1
    New Coder
    Join Date
    Jul 2005
    Posts
    12
    Thanks
    0
    Thanked 0 Times in 0 Posts

    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"

  • #2
    Senior Coder rnd me's Avatar
    Join Date
    Jun 2007
    Location
    Urbana
    Posts
    4,349
    Thanks
    11
    Thanked 589 Times in 570 Posts
    //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
    	]
    ]
    */
    Last edited by rnd me; 10-07-2012 at 06:34 PM.
    my site (updated 13/9/26)
    BROWSER STATS [% share] (2014/5/28) IE7:0.1, IE8:5.3, IE11:8.4, IE9:3.2, IE10:3.2, FF:18.2, CH:46, SF:7.9, NON-MOUSE:32%

  • #3
    New Coder
    Join Date
    Jul 2005
    Posts
    12
    Thanks
    0
    Thanked 0 Times in 0 Posts
    Thanks very much for taking the time to look at this. This worked perfectly and I appreciate it

    Thanks


  •  

    Tags for this Thread

    Posting Permissions

    • You may not post new threads
    • You may not post replies
    • You may not post attachments
    • You may not edit your posts
    •