代码之家  ›  专栏  ›  技术社区  ›  Matteo Tosato

Typescript中的GroupBy“Linq-like”

  •  0
  • Matteo Tosato  · 技术社区  · 8 年前

    比如:

    const grouping = items.groupBy('propValue');
    

    分组对象应该是像{key:string,values:any[]}这样的对象的集合

    2 回复  |  直到 8 年前
        1
  •  0
  •   Matteo Tosato    8 年前

    经过一些研究,我发现了这个解决方案:

    https://gist.github.com/guillaumegarcia13/668518119667594fdca150ebefecd194

    下面的原型支持嵌套属性和可选回调参数,以计算对元素的某些操作。

    /**
     * GroupBy array extension
     */
    
    interface Grouping<T> {
      key: string,
      values: Array<T>,
      computed: any
    }
    
    interface Array<T> {
      groupBy(prop: T, opCallBack: (group: Grouping<T>, item: T) => any): Grouping<T>[];
    }
    
    // Nested property support
    function getVal(obj, prop) {
      const props = prop.split('.');
      if (props.length === 1) {
        return obj[prop];
      } else {
        return getVal(obj[props[0]], prop.slice(prop.indexOf('.') + 1, prop.length));
      }
    }
    
    if (!Array.prototype.groupBy) {
      // Return an array of 'Grouping' object
      Array.prototype.groupBy = function (prop: string, opCallBack: (group: Grouping<any>, item: any) => any = null) {
        return this.reduce((data, item) => {
          // Get value
          const val = getVal(item, prop);
          // Search val
          if (data.filter(g => g.key === val).length === 0) {
            data.push({
              key: val,
              values: []
            });
          }
          if(opCallBack) {
            opCallBack(data.find(g => g.key === val), item);
          }
          data.find(g => g.key === val).values.push(item);
          return data;
        }, []);
      }
    }
    
    /* End */
    

    var a = [{a: 'aa', b: 45}, {a: 'aa', b: 45}, {a: 'aa', b: 2}, {a: 'cc', b: 4}, {a: 'cc', b: 45.6}, {a: 'bb', b: 1}];
    
    console.log(a.groupBy('a', (group, item) => { 
      group.computed = group.computed || 0; group.computed += item.b 
    }));
    
    // Log:
    [
        {
            "key": "aa",
            "values": [
                {
                    "a": "aa",
                    "b": 45
                },
                {
                    "a": "aa",
                    "b": 45
                },
                {
                    "a": "aa",
                    "b": 2
                }
            ],
            "computed": 92
        },
        {
            "key": "cc",
            "values": [
                {
                    "a": "cc",
                    "b": 4
                },
                {
                    "a": "cc",
                    "b": 45.6
                }
            ],
            "computed": 49.6
        },
        {
            "key": "bb",
            "values": [
                {
                    "a": "bb",
                    "b": 1
                }
            ],
            "computed": 1
        }
    ]
    

    我希望它能有用

        2
  •  0
  •   huserben    8 年前

    https://github.com/kutyel/linq.ts 如果您想使用LINQ中已知的其他方法。

    推荐文章