Transforming array of objects into named object in GROQ query

2 replies
Last updated: Feb 29, 2024
Hey folks, GROQ question
My document has an array of objects

hours: [
  { 
    day: "monday",
    from: "9:00AM",
    to: "5:00PM"
  },
  ...
]
I'm trying to transform those days with a GROQ query into a named object:

hours: {
  monday: {
    from: "9:00AM",
    to: "5:00PM"
  },
  ...
}
Is that something that's reasonable to do in the query? Or should I just reduce that manually client-side?
AI Update

Unfortunately, GROQ doesn't have built-in functionality to dynamically create objects with keys derived from field values. You cannot directly transform your array structure into an object keyed by the day field within a GROQ query.

The limitation is that GROQ doesn't support:

  • Dynamic object key creation from field values
  • Functions like object::merge() or similar reduce operations to build keyed objects
  • Using computed values as object keys in projections

Your best options:

1. Transform client-side (recommended)

This is the most practical approach. Query the array as-is and transform it with a simple reduce:

const result = await client.fetch(`*[_type == "yourType"][0]{ hours }`);

const hoursKeyed = result.hours.reduce((acc, item) => {
  acc[item.day] = { from: item.from, to: item.to };
  return acc;
}, {});

2. Restructure your schema

If you frequently need this keyed format, consider storing it as an object from the start:

hours: {
  monday: { from: "9:00AM", to: "5:00PM" },
  tuesday: { from: "9:00AM", to: "5:00PM" },
  // ...
}

This eliminates transformation needs, though it's less flexible if days vary.

3. Hardcode projections (not recommended)

If you have a fixed set of days, you could manually project each:

*[_type == "location"]{
  "hours": {
    "monday": hours[day == "monday"][0],
    "tuesday": hours[day == "tuesday"][0],
    "wednesday": hours[day == "wednesday"][0]
    // ... etc
  }
}

This works but is tedious and unmaintainable.

The bottom line: GROQ excels at querying and projecting data, not complex restructuring. For transformations like array-to-keyed-object conversions, client-side processing is the right tool. It's cleaner, more maintainable, and only adds a few lines of code.

You unfortunately can’t do this with GROQ. It’ll have to happen client-side.
okay makes sense, thanks!

Sanity – Build the way you think, not the way your CMS thinks

Sanity is the developer-first content operating system that gives you complete control. Schema-as-code, GROQ queries, and real-time APIs mean no more workarounds or waiting for deployments. Free to start, scale as you grow.

Was this answer helpful?