5

Let's say I have an array that looks like this:

const array = [0, 1, 2, 3, 4, 5, 6, 7]

What I'm trying to do is iterate for every 2 objects in a .map function, but it needs to look like something like this in my render (note that I'm using React Bootstrap):

<Row>
<Col>array[0]</Col>
<Col>array[1]</Col>
</Row>


<Row>
<Col>array[2]</Col>
<Col>array[3]</Col>
</Row>

etc...

So for every 2 objects, it needs to have it's own row, and then render those 2 objects before closing a Row and starting a new Row if it has more elements.

What's the best way to achieve this?

Andrew Bautista
  • 153
  • 2
  • 9
  • I don't know why it is reopened. [React: Render new row every 4th column](https://stackoverflow.com/questions/42391499) and [react.js every nth item add opening tag or closing tag](https://stackoverflow.com/questions/36318601) are duplicates. You need to create a 2D array of smaller chunks and map it – adiga Jul 13 '20 at 17:10
  • @adiga i've checked answers there.. they are not elegant as I expected. If you recommend to move my answer there and close this one,, please let me know. – Abdennour TOUMI Jul 13 '20 at 17:13
  • @AbdennourTOUMI I think you can keep it. The accepted answer is actually wrong. The other one is much more promising: https://stackoverflow.com/a/36318834/3082296 – adiga Jul 13 '20 at 17:16
  • Thank you @adiga . I love your contribution – Abdennour TOUMI Jul 13 '20 at 17:17

1 Answers1

14

short answer

Transform model, then inject in View.

Details answer

You need to convert your array to a matrix as per your need:

const array = [0, 1, 2, 3, 4, 5, 6, 7]

const rows = array.reduce(function (rows, key, index) { 
    return (index % 2 == 0 ? rows.push([key]) 
      : rows[rows.length-1].push(key)) && rows;
  }, []);
  
console.log(rows)

Now, you have your model is converted to this format

[ [0, 1] , [2, 3] , [4, 5] , [6, 7] ]

Now nested loop should do the job with elegance :

rows.map(row => ( 
  <Row >
  { row.map(col => (<Col>{col}</Col>)) }
  </Row>
))

NOTES:

The engineering behind this elegant solution is to prepare your model, then you loop.

Not sure, if React still requires id in (.e.g: <Compo id="">) when components are rendered in loop..

Abdennour TOUMI
  • 87,526
  • 38
  • 249
  • 254
  • This looks exactly like what I needed! I'm just trying to understand it though. What does index % 2 == 0 mean? – Andrew Bautista Jul 13 '20 at 18:26
  • @AndrewBautista it's creating the array into a 2D array with 2 items in the inner array. If it's too confusing you can use any of the answers on this question: [Split array into chunks](https://stackoverflow.com/questions/8495687) – adiga Jul 14 '20 at 12:48
  • @AndrewBautista so you are asking about ` index % 2 == 0`.. Actually, we want to group every 2 consecutive elements together... this means if the current iteration is in (index=0 ), (index=0) & (index=1) will be grouped together.. However, the next iteration will put us in (index=1), while (index=1) has already processed.. So we need to skip it.. In general, we need to skip iterations (1, 3, 5, ...).. The common thing among them is (index % 2 == 1). Got it! Skipping (index % 2 == 1) means we want (index % 2 == 0) and there is no other value for X%2. BTW, X%Y is the rest of dividing X by Y. – Abdennour TOUMI Jul 14 '20 at 23:28
  • @AbdennourTOUMI Thanks for this post! May I ask a question what this code `rows[rows.length-1].push(key)) && rows` do? Especially the `&&` part, I did not quite understand. – Seungho Lee Jan 22 '22 at 02:25