array.groupBy in TypeScript

后端 未结 4 1489
囚心锁ツ
囚心锁ツ 2021-02-19 19:01

The basic array class has .map, .forEach, .filter, and .reduce, but .groupBy i noticably absent, preventing me f

相关标签:
4条回答
  • 2021-02-19 19:03

    You can use the following code to group stuff using Typescript.

    const groupBy = <T, K extends keyof any>(list: T[], getKey: (item: T) => K) =>
      list.reduce((previous, currentItem) => {
        const group = getKey(currentItem);
        if (!previous[group]) previous[group] = [];
        previous[group].push(currentItem);
        return previous;
      }, {} as Record<K, T[]>);
    

    So, if you have the following structure and array:

    type Person = {
      name: string;
      age: number;
    };
    
    const people: Person[] = [
      {
        name: "Kevin R",
        age: 25,
      },
      {
        name: "Susan S",
        age: 18,
      },
      {
        name: "Julia J",
        age: 18,
      },
      {
        name: "Sarah C",
        age: 25,
      },
    ];
    

    You can invoke it like:

    const results = groupBy(people, i => i.name);
    

    Which in this case, will give you an object with string keys, and Person[] values.

    There are a few key concepts here:

    1- You can use function to get the key, this way you can use TS infer capabilities to avoid having to type the generic every time you use the function.

    2- By using the K extends keyof any type constraint, you're telling TS that the key being used needs to be something that can be a key string | number | symbol, that way you can use the getKey function to convert Date objects into strings for example.

    3- Finally, you will be getting an object with keys of the type of the key, and values of the of the array type.

    0 讨论(0)
  • 2021-02-19 19:06

    you could add the function to the array prototype in your app (note some don't recomend this: Why is extending native objects a bad practice?):

    Array.prototype.groupBy = function(/* params here */) { 
       let array = this; 
       let result;
       /* do more stuff here*/
       return result;
    }; 
    

    Then create an interface in typescript like this:

    .d.ts version:

        interface Array<T>
        {
            groupBy<T>(func:(x:T) => string): Group<T>[]
        }
    

    OR in a normal ts file:

    declare global {
       interface Array<T>
       {
          groupBy<T>(func:(x:T) => string): Group<T>[]
       }
    }
    

    Then you can use:

     props.tags.groupBy((t)=>t.category_name)
         .map((group)=>{
                        [...]
                    })
    
    0 讨论(0)
  • 2021-02-19 19:10

    Instead of groupby use reduce. Suppose product is your array

    let group = product.reduce((r, a) => {
    console.log("a", a);
    console.log('r', r);
    r[a.organization] = [...r[a.organization] || [], a];
    return r;
    }, {});
    
    console.log("group", group);
    
    0 讨论(0)
  • 2021-02-19 19:28

    A good option might be lodash.

    npm install --save lodash
    npm install --save-dev @types/lodash
    

    Just import it import * as _ from 'lodash' and use.

    Example

    _.groupBy(..)
    _.map(..)
    _.filter(..)
    
    0 讨论(0)
提交回复
热议问题