S
S
Sanches2014-01-31 23:16:19
JavaScript
Sanches, 2014-01-31 23:16:19

Iterating a javascript object into groups of N elements?

There is a collection object with other objects containing data from several pages.
You need to display the data of these pages as a list, but broken down by 16 elements.
I use DocPad and Jade as a templating engine.
The code looks like this:

- var projects = getCollection('projects').toJSON()
- var count = projects.length
- var pages = Math.ceil(count / 16)

.entry-list
    each project in projects
        - for ( var page = 1; page <= pages; page++ )
            .entry-list-page
                - for (var item = 1; item <= 16; item++,count-- )
                    - if (count > 0)
                        .hentry
                            a(href=project.url).entry-link
                                h3= project.title
                    - else
                        .hentry.emty

Missing elements are displayed empty (.empty).
Naturally, the first for works out completely for each project, which leads to completely different results.
And you want to get something like this:
.entry-list
    .entry-list-page.page1
        .hentry
            a(href="page1.html").entry-link
                h3= title1
        .hentry
            a(href="page2.html").entry-link
                h3= title2
...
        .hentry
            a(href="page16.html").entry-link
                h3= title16
 
    .entry-list-page.page2
        .hentry
            a(href="page17.html").entry-link
                h3= title17
        .hentry
            a(href="page18.html").entry-link
                h3= title18
...
        .hentry
            a(href="page30.html").entry-link
                h3= title30
        .hentry.emty
        .hentry.emty

I would be grateful for the help, my knowledge is not enough here.
UPD. For me the solution was this:
- var projects = getCollection('projects').toJSON()
- var count = projects.length
- var ppage = 16
- var pages = Math.ceil(count / ppage)

.entry-list

    - for ( var cpage = 1; cpage <= pages; cpage++ )
        - var projectsPage = projects.splice(0,ppage)  // вырезаем первые 16 элементов
        .entry-list-page

            each project in projectsPage               // Итерируем вырезанные элементы
                .hentry
                    a(href=project.url).entry-link
                        h3= project.title

            - var ecount = ppage - projectsPage.length // Если элементов оказалось меньше нужного,
            - for ( var i = 0; i < ecount; i++  )      // заполняем нехватку
                .hentry.empt                           // пустыми блоками

Answer the question

In order to leave comments, you need to log in

2 answer(s)
S
Sanches, 2014-02-02
@Sanches

Thank you very much for your help, but, unfortunately, your variant does not work either - Jade does not have endif and it closes the .entry-list-page block immediately after processing.
But it doesn't matter anymore, I discovered the magic splice method for myself), the solution with it is in the UPD.

D
Danny Chernyavsky, 2014-02-01
@DEHisOK

Good afternoon!
I think it's some kind of pun. I don’t quite understand: is each project divided into pages or are projects displayed on the pages?
Based on your code, we can conclude that both this and that is impossible :)
Also, I want to note that I have not dealt with this template engine, but, in my opinion, something like this should come out:

- var projects = getCollection('projects').toJSON()
- var count = projects.length
- var ppage = 16 // per page
- var pages = Math.ceil(count / ppage)
- var cpage = 1 // current page

// добавляем пустые элементы в projects
- if (count < ppage*pages)
  - for (var n = count+1; n <= ppage*pages; n++)
    projects[n] = null

.entry-list
    each project, i in projects
    	- if (i == (1 + ppage * (cpage - 1)))	// 1,17,33,etc
        .entry-list-page.page$cpage				// не знаю, как вывести переменную
        // тут, возможно, нужен endif какой-то

        	- if (project != null)
            .hentry
                a(href=project.url).entry-link
                    h3= project.title
            - else
            .hentry.empty

Instead of adding empty elements to projects, one could simply do another for after each (when it ends), which would add "empty" tags, but, as far as I understand, this cannot be done, because the .entry-list-page.page2 div will be closed inside the last iteration of each.
Based on this, there is another option:
- var projects = getCollection('projects').toJSON()
- var count = projects.length
- var ppage = 16 // per page
- var pages = Math.ceil(count / ppage)
- var cpage = 1 // current page

.entry-list
    each project, i in projects					// это подсмотрел на stackoverflow, должно возвращать индекс
    	- if (i == (1 + ppage * (cpage - 1)))	// 1,17,33,etc
        .entry-list-page.page$cpage				// не знаю, как вывести переменную
        // тут, возможно, нужен endif какой-то

            .hentry
                a(href=project.url).entry-link
                    h3= project.title

            - if (i == count && count < ppage*pages)
            	- for (var n = count+1; n <= ppage*pages; n++)
            	.hentry.empty

Sorry if my ideas are just confusing, but algorithmically this should work.
You need to fix the output of the variable and check each.
Well, and all other syntax elements :)

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question