set properties on first 4 objects in array, then restart sequence on 5th object, 9th object etc

I’m working with a sanity.io project. I fetch some data, store it in an array and then push it to my front-end with express and ejs.

Each post that’s getting stored in my array will be displayed as a card. Each card will have a different css class on it to be displayed as either a small card, medium card, large card or XL card.

So my goal is to loop through the array, and attach a property to each object to access on the front end to determine what size the card will be.

It would essentially look like this, but this would obviously not scale since I’ll be uploading new posts to the website through sanity.io

  // desired result
  posts[0].size = 's'
  posts[1].size = 'm'
  posts[2].size = 'l'
  posts[3].size = 'xl'

  posts[4].size = 's'
  posts[5].size = 'm'
  posts[6].size = 'l'
  posts[7].size = 'xl'

So I’m thinking that I have to loop through the array, attach the properties to the first 4 objects, and then restart the sequence for the following 4 objects, then the following next 4 etc etc.

let items = [];


// fetch and push to array
client.fetch(query).then((posts) => {
  posts.forEach((post) => {
    items.push(post);
  });

  
  // set properties on first 4 objects, restart sequence on 5th, 9th etc.
  for(let i = 0; i < posts.length; i+=4){
    posts[i].size = 's'
    posts[i].size = 'm'
    posts[i].size = 'l'
    posts[i].size = 'xl'
  }
  
});

That last block of code is super wrong but it’s just the point I’m at right now. I would really appreciate any help or pointers on this

Answer

Create an array of sizes. Map the posts, and for each post use object spread to create a new object, with the size. Take the size value from the array. To get the relevant size for the post use the current post’s index remainder (%) from the sizes array length.

Note: you are using an async fetch, use promises or async await to create the items instead of pushing it directly.

const sizes = ['s', 'm', 'l', 'xl'];

const items = await client.fetch(query).then(posts =>
  posts.map((post, index) => ({ 
    ...post,
    size: sizes[index % sizes.length] 
  }))  
);

Example:

const fetch = () => Promise.resolve([{ title: 'a' }, { title: 'b' }, { title: 'c' }, { title: 'd' }, { title: 'e' }, { title: 'f' }]);

const sizes = ['s', 'm', 'l', 'xl'];

const example = async () => {
  const items = await fetch().then(posts =>
    posts.map((post, index) => ({ 
      ...post, 
      size: sizes[index % sizes.length] 
    }))  
  );
  
  console.log(items);
}

example();