Wolf
Wolf

Reputation: 33

How to get a unique index for nested loops in Svelte Kit

I'm creating a website for uploading images. You can create albums, and each album can contain a number of posts. There are numerous photos in each post (a array of images).

It looks like the following:

const albums = [
    {
        id: 1,
        title: 'Album 1',
    }
]

const posts = [
    {
        "album": 1,
        "images": [
            "https://picsum.photos/200/300",
            "https://picsum.photos/200/300",
        ],
        "author": 1,
    },
    {
        "album": 1,
        "images": [
            "https://picsum.photos/200/300",
        ],
        "author": 2,
    },
    {
        "album": 1,
        "images": [
            "https://picsum.photos/200/300",
            "https://picsum.photos/200/300",
            "https://picsum.photos/200/300",
            "https://picsum.photos/200/300",
            "https://picsum.photos/200/300",
        ],
        "author": 4,
    }
]

For each post image in the array, I need to obtain a distinct index number. How I'm trying to obtain it in Svelte is as following:

{#each posts as post}
    {#each post.images as image, index}
        {index}: {image}
    {/each}
{/each}

However, this won't give me an unique index for every image. It will result in the following:

0: https://picsum.photos/200/300
1: https://picsum.photos/200/300
0: https://picsum.photos/200/300
0: https://picsum.photos/200/300
1: https://picsum.photos/200/300
2: https://picsum.photos/200/300
3: https://picsum.photos/200/300
4: https://picsum.photos/200/300

Except, I need it like this:

0: https://picsum.photos/200/300
1: https://picsum.photos/200/300
2: https://picsum.photos/200/300
3: https://picsum.photos/200/300
4: https://picsum.photos/200/300
5: https://picsum.photos/200/300
6: https://picsum.photos/200/300
7: https://picsum.photos/200/300

How would I be possible to achieve the above one?

One thought of mine would be reducing/mapping the array and creating a post object for each single image. However, I'm unsure how to achieve this.

Upvotes: 2

Views: 9654

Answers (3)

Hyunbin
Hyunbin

Reputation: 753

Why not use both indexes?

<script>
  const posts = [
    {
      album: 1,
      images: ['https://picsum.photos/200/300', 'https://picsum.photos/200/300'],
      author: 1,
    },
    {
      album: 1,
      images: ['https://picsum.photos/200/300'],
      author: 2,
    },
    {
      album: 1,
      images: ['https://picsum.photos/200/300', 'https://picsum.photos/200/300'],
      author: 4,
    },
  ];
</script>

<ul>
  {#each posts as post, index}
    {@const postIndex = index}
    {#each post.images as _, index}
      {@const imageIndex = index}
      {@const uniqueId = `${postIndex}:${imageIndex}`}
      <li>{uniqueId}</li>
    {/each}
  {/each}
</ul>

<!--
0:0
0:1
1:0
2:0
2:1
-->

Upvotes: 0

Bob Fanger
Bob Fanger

Reputation: 29917

Generate a nested array containing the desired numbers:

<script>
  // const posts = ...

  $: numbers = buildNumbers(posts)

  function buildNumbers(posts) {
    let nr = 1
    const result = []
    posts.forEach((post, postIndex) => {
      post.images.forEach((image, imageIndex) => {
        result[postIndex] = result[postIndex] || []
        result[postIndex][imageIndex] = nr
        nr++
      })
    })
    return result
  }
</script>

<ul>
{#each posts as post, postIndex}
  {#each post.images as image, imageIndex}
    <li>{numbers[postIndex][imageIndex]}: {image}</li>
  {/each}
{/each}
</ul>

REPL

Upvotes: 1

PeterSH
PeterSH

Reputation: 475

You can create a "getter" function to get all the images from every post

function getImages() {
    return posts.map(post => post.images).flat()
}

And use that instead of two nested each loops

{#each getImages() as image, index}
    {index}: {image}
{/each}

Upvotes: 4

Related Questions