0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

TypeScriptでC#LIKEなgroupBy拡張メソッドを追加

Posted at

イントロ

TypeScript勉強中
配列操作でgroupByっぽいメソッドが無いことを発見。

linqのnpmパッケージを使用すれば解決できるが
https://www.npmjs.com/package/linq

Enumerable.from(hoge).groupBy();

という具合に、Enumerableに食わせてあげる必要があった。

C#のLINQの書き方が好みなので
C#LIKE な ドット演算子でつなげて記述できるよう 試行錯誤してみた。

実装

array.extensions.ts
export {};

declare global {
  interface Array<T>
  {
     groupBy<K extends PropertyKey>(callbackfn: (value: T, index: number, array: readonly T[]) => K): {key: K, values: T[]}[];
  }
}

Array.prototype.groupBy = function<T, K extends PropertyKey>(callbackfn: (value: T, index: number, array: readonly T[]) => K): {key: K, values: T[]}[] {
  const entities = this as T[];
  return entities.reduce((ret, cur, idx, src) => {
    const key = callbackfn(cur, idx, src);
    let values = ret.find(e => e.key === key);
    if (values === undefined) { ret.push({key: key, values: [cur]}); }
    else { values.values.push(cur); }
    return ret;
  }, [] as {key: K, values: T[]}[]);
}

上記を実装することで [].groupBy() というように Arrayの拡張メソッドを生やせるようになる

使用例

ユーザ配列内の rank毎に グルーピングする例

index.ts
import './array.extensions';

class User {
  constructor(
    public name: string,
    public rank: number,
  ) {}
}

let users: User[] = [
  new User('aaa', 1),
  new User('bbb', 2),
  new User('ccc', 1),
  new User('ddd', 3),
];

users.groupBy(e => e.rank)
     .filter(e => e.key !== 2)
     .forEach(e => {
       console.log(`rank: ${e.key}`);
       console.log(`names: ${e.values.map(e => e.name)}`);
      });
結果.
rank: 1
names: aaa,ccc
rank: 3
names: ddd

まとめ

linq packageの方が機能がおおく優秀ではありますが、
.演算子で繋げたいという方はぜひ

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?