Unlock seamless workflows and faster delivery with our latest releases ā€“ get the details

How to flatten an array of arrays of objects using Groq in Sanity.io.

7 replies
Last updated: Feb 9, 2022
Hello! Is there any way to flatten an array of arrays of objects?I have:

backgrounds: [
  [{ asset: {...} }],
  [{ asset: {...} }]
]
Which I want to, with Groq, turn into:

thumbnails: [
  { asset: {...} },
  { asset: {...} }
],
So far I've tried things like below, to no avail:

'thumbnails': ...backgrounds[]->{
  backgrounds[]{asset}
}
// Unexpected prefix operator "dotDotDot", which makes sense

'thumbnails': [...backgrounds[]->{
  backgrounds[]{asset}
}]
// Nothing flattened

'thumbnails': [...backgrounds[]->{
  ...backgrounds[]{asset}
}]
// thumbnails: [ {}, {} ]

'thumbnails': [...backgrounds[]->{
  backgrounds[]{asset}
}.backgrounds]
// Nothing flattened
I'm guessing I'm missing something obvious here, but I can't seem to figure it out
Feb 8, 2022, 10:47 AM
What does the schema itself look like that produces those object arrays?
Feb 8, 2022, 3:05 PM
export default {
  title: 'Background list',
  name: 'backgrounds',
  type: 'document',
  fields: [
    {
      localize: false,
      title: 'Name',
      description: 'A short name describing what this list of backgrounds contains.',
      name: 'text',
      type: 'string',
    },
    {
      title: 'Backgrounds',
      name: 'backgrounds',
      type: 'array',
      of: [{ type: 'image', options: { accept: 'image/*' } }],
    },
  ],
};

Feb 8, 2022, 4:02 PM
I think because the assets are similar to a kind of reference, in the sense that they can be "pushed forward" to resolve their constituent elements, something like asset-> might be more effective than spread syntax or leaving the word asset by itself.
I am far more intrigued by a document type and a field sharing name. I am sure it can tell the difference based on type and requested hierarchy but in case it can't, I wonder if you could resolve the query for fields to something more...explicit? Like setting your own projection name, but mapping it to the document with an @ or ^, depending on the context?

I apologize that I couldn't help easily this time; hopefully someone more knowledgeable will be along soon.
Feb 8, 2022, 4:12 PM
Thanks for the replies User and User! (Note I've changed some names to see if the scoping thing you mentioned changes anything,
user S
)
'backgroundLists': backgroundLists[].asset->,
as you suggest
user M
gives me
"backgrounds": [
  null,
  null
]
which makes sense since
backgroundLists
is an array of references to an array of images, and you of course simply wanted to point me in the right direction, it works with something like
'backgroundLists': backgroundLists[]->.backgrounds[].asset,
. Thanks again, both of you. Going to check whether the scoping thing actually made any difference too.
Feb 9, 2022, 8:01 AM
Shared naming seems to make no difference šŸ‘
Feb 9, 2022, 8:03 AM
(other than being far more readable with more specific names šŸ˜…)
Feb 9, 2022, 8:03 AM
Interesting. After reading the thread top to bottom I was going to next try the last bit except ending in []->.asset and see if that worked to open it up then crawl it at the same time. I like GROQ but I'm still learning myself. I would love in some of the documentation if it would stay in the context of one kind of attempted use case so the pivots between different syntax had added clarity for situations like this, because I'm realizing how soon in the process my next step would be to just bang on it with trial and error.
I am going to try to reproduce this schema in a test project so I can do that. Hopefully later tonight unless you're able to find a solution by then.
Feb 9, 2022, 12:27 PM

Sanityā€“ build remarkable experiences at scale

Sanity is a modern headless CMS that treats content as data to power your digital business. Free to get started, and pay-as-you-go on all plans.

Was this answer helpful?