14

Lets say I have an array of services objects

services: [{title: title, caption: caption},{title: title, caption: caption},{title: title, caption: caption},{title: title, caption: caption}]

The end result is a mapped array with every two elements in it's own div.

<div>
 <div>services[0]</div>
 <div>services[1]</div>
</div>
<div>
 <div>services[2]</div>
 <div>services[3]</div>
</div>

I cant wrap my head around how I would achieve this? Map and split the array by every two elements? Split the array into two arrays, then map that? Is it to early in the morning? Yes it is.

jobiin
  • 449
  • 2
  • 5
  • 12

4 Answers4

13

Yes, one way to do it is to group the array by every two elements, but you'd do that by using reduce.

The callback for reduce can actually take four arguments, and you can initialize the accumulator with an empty array, so it ends up looking like this:

const services = [{
  title: 'title0',
  caption: 'caption0'
}, {
  title: 'title1',
  caption: 'caption1'
}, {
  title: 'title2',
  caption: 'caption2'
}, {
  title: 'title3',
  caption: 'caption3'
}];

services
  .reduce((accumulator, currentValue, currentIndex, array) => {
    if (currentIndex % 2 === 0) {
      accumulator.push(array.slice(currentIndex, currentIndex + 2));
    }
    return accumulator;
  }, [])
  .forEach(p => console.log(p[0], p[1]));
double-beep
  • 5,031
  • 17
  • 33
  • 41
Matthew Lowe
  • 1,350
  • 1
  • 17
  • 29
  • @OmamaZainab the intention is to split the array into pairs, so I'm not sure what it would mean for it to "work" if the array had an odd number of items. – Matthew Lowe Oct 08 '20 at 13:09
2

You could use for loop that increments by 2 and inside map method to create string and after add it to html.

const data = [{title: 'title', caption: 'caption'},{title: 'title', caption: 'caption'},{title: 'title', caption: 'caption'},{title: 'title', caption: 'caption'}, {title: 'title', caption: 'caption'}]

let html = '';
for(var i = 0; i < data.length; i += 2) {
  const divs = data
    .slice(i, i + 2)
    .map(({title, caption}) => `<div>${title} | ${caption}</div>`)
    .join('')
    
  html += `<div>${divs}</div>`;
}

document.body.innerHTML += html;
Nenad Vracar
  • 118,580
  • 15
  • 151
  • 176
2

Use (index % 2) to close and open the new div.

var array = [
 {title: 'title', caption: 'caption'},
 {title: 'title', caption: 'caption'},
 {title: 'title', caption: 'caption'},
 {title: 'title', caption: 'caption'},
 {title: 'title', caption: 'caption'},
 {title: 'title', caption: 'caption'}
]

var html = '<div class="row">'
array.forEach(function (item, index) {
 html += '<div>' + item.title + '</div>'
 html += '<div>' + item.caption + '</div>'
 if (index % 2) {
  html += '</div><div class="row">'
 }
})

html += '</div>'

document.getElementById('result').insertAdjacentHTML('beforeend', html)
.row {
 margin: 20px 0px;
 background-color: #DDD;
}
<div id='result'></div>
Axel
  • 66
  • 1
  • 9
0

Just loop the items in groups of two ...

var services = [
    {title: 'title1', caption: 'caption1'},
    {title: 'title2', caption: 'caption2'},
    {title: 'title3', caption: 'caption3'},
    {title: 'title4', caption: 'caption4'}
];

for (var i = 0; i < services.length; i += 2) {
  document.body.innerHTML += '<div><div>' + services[i].title + '</div>' + 
                             '<div>' + services[i + 1].title + '</div></div>';
}
eisbehr
  • 12,243
  • 7
  • 38
  • 63