Skip to content

How to join two arrays by their properties?

Joining two arrays by a shared property is straightforward in fx because you write plain JavaScript. No need to learn a DSL like jq — just use familiar map, find, objects, and optional chaining.

Below are two common approaches using the same input. The first is simple and expressive; the second is faster for large arrays.

Example data

json
{
  "posts": [
    { "id": 1, "title": "Hello", "author": 10 },
    { "id": 2, "title": "World", "author": 20 }
  ],
  "users": [
    { "id": 10, "name": "Alice" },
    { "id": 20, "name": "Bob" }
  ]
}

Using find

Use Array.prototype.find inside a map over the left-hand side array. This is essentially a left join: if the author is missing, you’ll get undefined (or whatever fallback you provide).

bash
fx data.json 'x.posts.map(p => ({
  title: p.title,
  author: x.users.find(y => y.id == p.author)?.name
}))'

Output:

json
[
  { "title": "Hello", "author": "Alice" },
  { "title": "World", "author": "Bob" }
]

Notes:

  • Optional chaining (?.) avoids errors when there’s no match.
  • For small arrays this is perfectly fine. For very large arrays it’s O(n·m) and may be slower.

Build a lookup map

Precompute a dictionary from users keyed by id, then do a single pass over posts. This makes the join O(n + m).

bash
fx data.json 'x => {
  const names = {};
  x.users.forEach(y => names[y.id] = y.name);
  return x.posts.map(p => ({ ...p, author: names[p.author] }))
}'

Output:

json
[
  { "id": 1, "title": "Hello", "author": "Alice" },
  { "id": 2, "title": "World", "author": "Bob" }
]

One-to-many joins

Sometimes the right-hand side has multiple matches for a single left-hand row. In a one-to-many join you typically produce an array of matches per left item.

This mirrors the earlier find example, but uses filter to collect all matches:

bash
fx data.json 'x.users.map(u => ({
  id: u.id,
  name: u.name,
  posts: x.posts.filter(p => p.author == u.id)
}))'

Output:

json
[
  {
    "id": 10,
    "name": "Alice",
    "posts": [
      { "id": 1, "title": "Hello", "author": 10 }
    ]
  },
  {
    "id": 20,
    "name": "Bob",
    "posts": [
      { "id": 2, "title": "World", "author": 20 }
    ]
  }
]