Ogbobe Buko Ogbobe Buko - 2 days ago 4
Javascript Question

Grouping an Array and Counting items creating new array based on Groups

My knowledge on manipulating arrays is really poor, i was wandering if i could get any help with this. i have an

array("dataResult")
.that has got Region, Fruits and User information. i want to Group this information based on Region and also count the number of unique users for each group.

dataResult = [{ region: "Africa", fruit: "Orange", user: "Gary" },
{ region: "Africa", fruit: "Apple", user: "Steve" },
{ region: "Europe", fruit: "Orange", user: "John" },
{ region: "Europe", fruit: "Apple", user: "bob" },
{ region: "Asia", fruit: "Orange", user: "Ian" },
{ region: "Asia", fruit: "Apple", user: "Angelo" },
{ region: "Africa", fruit: "Orange", user: "Gary" }]`


I would like my final array to look like the array below to reflect the grouped result and count of unique users for each group

NewResult = [{ region: "Africa", count: 2 }, { region: "Europe", count: 2},{ region: "Asia", count: 2}],


Any ideas on how this can be acheived? i have seen some good info on how to group results but i'm struggling with getting the count for uniques user for each group.

Code for Grouping

var categoryNames = groupBy(dataResults, '2');
console.log(categoryNames);

function groupBy(items,propertyName)
{
var result = [];
$.each(items, function(index, item) {
if ($.inArray(item[propertyName], result)==-1) {
result.push(item[propertyName]);
}
});
return result;
}

Answer

With proper data, you could iterate the array of objects and count the regions.

var dataResult = [{ region: "Africa", fruit: "Orange", user: "Gary" }, { region: "Africa", fruit: "Apple", user: "Steve" }, { region: "Europe", fruit: "Orange", user: "John" }, { region: "Europe", fruit: "Apple", user: "bob" }, { region: "Asia", fruit: "Orange", user: "Ian" }, { region: "Asia", fruit: "Apple", user: "Angelo" }, { region: "Africa", fruit: "Orange", user: "Gary" }],
    grouped = [];

dataResult.forEach(function (a) {
    if (!this[a.region]) {
        this[a.region] = { region: a.region, count: 0 };
        grouped.push(this[a.region]);
    }
    this[a.region].count++;
}, Object.create(null));
  
console.log(grouped);
.as-console-wrapper { max-height: 100% !important; top: 0; }

For unique user, you might use an extended hash table

var dataResult = [{ region: "Africa", fruit: "Orange", user: "Gary" }, { region: "Africa", fruit: "Apple", user: "Steve" }, { region: "Europe", fruit: "Orange", user: "John" }, { region: "Europe", fruit: "Apple", user: "bob" }, { region: "Asia", fruit: "Orange", user: "Ian" }, { region: "Asia", fruit: "Apple", user: "Angelo" }, { region: "Africa", fruit: "Orange", user: "Gary" }],
    grouped = [];

dataResult.forEach(function (a) {
    var key = [a.region, a.user].join('|');
    if (!this[a.region]) {
        this[a.region] = { region: a.region, count: 0 };
        grouped.push(this[a.region]);
    }
    if (!this[key]) {
        this[key] = true;
        this[a.region].count++;
    }
}, Object.create(null));
  
console.log(grouped);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Part with a decent look at the hash table and some explanations in the code.

var dataResult = [{ region: "Africa", fruit: "Orange", user: "Gary" }, { region: "Africa", fruit: "Apple", user: "Steve" }, { region: "Europe", fruit: "Orange", user: "John" }, { region: "Europe", fruit: "Apple", user: "bob" }, { region: "Asia", fruit: "Orange", user: "Ian" }, { region: "Asia", fruit: "Apple", user: "Angelo" }, { region: "Africa", fruit: "Orange", user: "Gary" }],
    grouped = [],               // result array
    hash = Object.create(null); // oposite of {}, this object does not contain any prototypes

dataResult.forEach(function (a) {

    // build key with region + name, spot pipe in hash
    var key = [a.region, a.user].join('|');

    // check if region is not in hash table
    if (!this[a.region]) {

        // create new object with region and count and insert it into hash table
        this[a.region] = { region: a.region, count: 0 };

        // push the object to the result
        grouped.push(this[a.region]);
    }

    // check if if not region and user exists, it means
    // the user in the region is not counted yet.
    if (!this[key]) {

        //create hash entry
        this[key] = true;

        // increment count 
        this[a.region].count++;
    }
}, hash);
  
console.log(hash);
console.log(grouped);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Comments