Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How could I use map to render a list of items but grouped at every 3 items?

I have a long list of items in an array. These need to be rendered in a component, which should be all fine and dandy. However, I need these to be wrapped by another component at every 3 items.

So, if I were to just render the items it would look like this:

return (
  <div>
    items.map((x, index) => {
      <span key={index}>{x}</span>
    })
  </div>
)

But basically, I want every three items to be wrapped inside a div with a special class, so something like this:

return (
  <div>
    <div className='group-of-3'>
      <span>Item 1</span>
      <span>Item 2</span>
      <span>Item 3</span>
    </div>
    <div className='group-of-3'>
      <span>Item 4</span>
      <span>Item 5</span>
      <span>Item 6</span>
    </div>
    .
    .
    .
  </div>
)

What would be the ideal way to do this? Keep in mind that the amount of items does change, so doing it manually is out of the question.

like image 456
theJuls Avatar asked Dec 23 '22 00:12

theJuls


1 Answers

Using plain JavaScript, you can use Array.reduce() to create subarrays from your items. Then map on your items twice:

const group = (items, n) => items.reduce((acc, x, i) => {
  const idx = Math.floor(i / n);
  acc[idx] = [...(acc[idx] || []), x];
  return acc;
}, []);

function Example({ items }) {
  return (
    <div>{group(items, 3).map(children =>
        <div className='group-of-3'>
          {children.map((x, i) => <span key={i}>{x}</span>)}
        </div>
    )}</div>
  );
}

ReactDOM.render(
  <Example items={[1, 2, 3, 4, 5, 6, 7, 8]} />,
  document.getElementById('root')
);
.group-of-3 {
  border: 1px solid black;
  padding: 5px;
  margin: 5px;
  width: 50px;
  text-align: center;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="root"></div>
like image 179
jo_va Avatar answered Dec 26 '22 00:12

jo_va