简体   繁体   English

打字稿中的 GroupBy 'Linq like'

[英]GroupBy 'Linq like' in Typescript

I was looking for a 'groupBy' method in Typescript but it still seems not implemented natively.我一直在寻找 Typescript 中的“groupBy”方法,但它似乎仍未在本地实现。

Like:喜欢:

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

The grouping object should be a collection of objects like {key:string, values:any[]}分组对象应该是一个对象的集合,比如 {key:string, values:any[]}

After some research, I found this solution:经过一番研究,我找到了这个解决方案:

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

Anyway, I structured it a little bit more to have a better typing for my purposes.无论如何,为了我的目的,我对它进行了更多的结构化处理,以便更好地打字。

The following prototype, supports nested properties and a optional callback parameter to compute some operation on the elements.以下原型支持嵌套属性和可选的回调参数来计算对元素的一些操作。

/**
 * 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 */

An example:一个例子:

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
    }
]

I hope it can be useful我希望它有用

This might not be built-in by default, but there exists a project that brings you linq-like functions to typescript.默认情况下这可能不是内置的,但是有一个项目可以为您提供类似 linq 的函数到 typescript。 I suggest that you have a look at the linqts project at https://github.com/kutyel/linq.ts in case you want to use other methods known from LINQ.如果您想使用 LINQ 已知的其他方法,我建议您查看https://github.com/kutyel/linq.ts上的 linqts 项目。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM