Standard lib for more array operations? (union, intersection, etc.)

Does anyone know of bindings or a library for these common array operatons? union, intersection, difference, etc? I’ve been writing my own when I have to, but they’re pretty crude and unoptimized.

This doesn’t directly answer your question, but have you looked into using the Belt.Set module? It has the functions you mention, and its set data type will be more optimized for those kinds of operations than using arrays. You can use Belt.Set.Int or Belt.Set.String to compare sets of ints and strings, or use the polymorphic Belt.Set with your custom data types.

2 Likes

Yes, I’ve used Belt.Set to optimize a few of these (union just requires writing two string arrays to the same set then converting back to an array).

It gets harder with more complex data types that aren’t easily toString’able.

You don’t necessarily need to convert the data types to strings. With the polymorphic Belt.Set all you need is a comparison function for your type.

Example:

type t = {foo: int, bar: string}

let compare = (a, b) =>
  switch compare(a.foo, b.foo) {
  | 0 => compare(a.bar, b.bar) // If foo is equal, compare bar
  | x => x
  }

module Id = Belt.Id.MakeComparable({
  type t = t
  let cmp = compare
})

let empty_set = Belt.Set.make(~id=module(Id))
let x = Belt.Set.add(empty_set, {foo: 1, bar: "a"})
let y = Belt.Set.add(empty_set, {foo: 2, bar: "b"})
let z = Belt.Set.union(x, y)
3 Likes

Ah nice- yeah that certainly simplifies it. I also didn’t realize Belt.Set has union, intersect, and diff functions. 🤦 Thanks!

1 Like