Home > Back-end >  GroupBy and count objects in an array in typescript
GroupBy and count objects in an array in typescript

Time:11-30

This is how my array looks like:

["Car","model","year","color","price"]
["Table","model","year","color","price"]
["Car","model","year","color","price"]
["Car","model","year","color","price"]
["Laptop","model","year","color","price"]
["Laptop","model","year","color","price"]

now I want to group by this in typescript and count how many of that item exist in array (also like in sql)

name  |count
 Car  | 3
Laptop| 2
Table | 1

and in my typescript file I have this

private groupByObjects() {
  //this read all data in array allData[] from service
  this.dataService.retrieveData().subscribe(allData => {

});

}

Could anyone please help me to write this in typescript?

CodePudding user response:

You can do this is O(n) through a simple reduction

In your case,

type 2DArray<T = string> = Array<Array<T>>

const groupAndApplyByIndex<T, R>(data: 2DArray<T>, index: number, apply: (element?: T) => R): Record<string, R> => {
  return data.reduce((counts, element) => (
    ...counts,
    [element[index]]: apply(element[index])
  }), {})
}

And just use the above funtion in your code by:

private groupByObjects() {
  //this read all data in array allData[] from service
  this.dataService.retrieveData().subscribe(allData => {
    counts = groupAndCountByIndex(allData, 0, (element) => (element || 0)   1))
    // Rest of your logic...
  });

By using the above method, you have a function which can count or do other transformations that you define through apply

CodePudding user response:

I like the approach of a list reducer using a function that return another function. That way you can always specify which key to use, in your case this key is 0.

interface PropObject {
  [index: string]: number;
}

const groupByCounter = (key : number) => (result : PropObject ,current : string []) => {
  const item = Object.assign({},current);
  if (typeof result[current[key]] == 'undefined'){
    result[current[key]] = 1;
  }else{
    result[current[key]]  ;
  }
  return result;
};

const data : string [][] = [["Car","model","year","color","price"],
["Table","model","year","color","price"],
["Car","model","year","color","price"],
["Car","model","year","color","price"],
["Laptop","model","year","color","price"],
["Laptop","model","year","color","price"]];

const group = data.reduce(groupByCounter(0),{});
console.log(group);

Link to typescript playground.

Check out the javascript version

  • Related