jsでオブジェクト配列をつかった集合演算

はじめに

jsで集合演算についてしらべてみた。
調べた限り集合演算の例は[1,2,3]と[2,3,4]の積集合をもとめるといったプリミティブ値の配列が多くて、オブジェクト配列をつかった 集合演算が見つからなかったので、残して見ようと思う。

問題(特定の本の返却期日をしらべる)

たとえば、ある人が本屋から複数の本をレンタルしてたときを考えてみる。
レンタルしている本は、id、名前とサイズともつ(A)
本屋はレンタルした本のidと返却期日を保管している(B)

レンタルしてる本からサイズが小さいものの返却期日を調べるにはどうすればよいか?
(A)の部分集合の返却期日を(B)から得たいというわけです。

これらをコードで記述すれば、

// (A) レンタルしてる本一覧
const books = [
  { id: 1, name: 'book1', size: 'large' },
  { id: 2, name: 'book2', size: 'small' },
  { id: 3, name: 'book3', size: 'medium' },
  { id: 4, name: 'book4', size: 'medium' },
  { id: 5, name: 'book5', size: 'small' },
];

// (B) レンタルしている本の返却期日一覧
const lends = [
  { id: 1, end_on: '2019-01-01' },
  { id: 2, end_on: '2019-02-01' },
  { id: 3, end_on: '2019-01-11' },
  { id: 4, end_on: '2019-01-22' },
  { id: 5, end_on: '2019-01-11' },
];

サイズがsmallのものは、idが2,5である。
これの返却期日をlendsから得ると次のとおりになる。

// もとめたいもの(サイズがsmall)
[
  { id: 2, end_on: '2019-02-01' },
  { id: 5, end_on: '2019-01-11' },
]

解決方法

books
  .filter(book => book.size === 'small')  // (1)
  .map(target => lends.find(lend => lend.id === target.id)) // (2)

(1): booksから特定サイズの部分集合をえる

(2): (1)で得た部分集合のidと同じidをもつものをfindで取得してmapで配列を返す

さいごに

jsでオブジェクト配列から積集合?をもとめる書き方を紹介してみました。

使えるときがあるのかな笑
SQLで書くと、

select L.id, L.end_on from books B where size = 'small' left join lends L on B.id = L.id

を求めたいわけでした。

jsで集合演算というとSetという演算子がつかえるみたいですね。
Setをつかって今回の問題はとけるのかな...