Map an Array by every two elements
Asked Answered
V

5

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.

Vann answered 26/3, 2018 at 12:25 Comment(1)
How are you creating the html?Aikido
F
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]));
Fluorescence answered 5/3, 2019 at 21:12 Comment(1)
@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.Fluorescence
A
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;
Anchylose answered 26/3, 2018 at 12:35 Comment(1)
Is it possible for some values of the array to be missed if the length is not an odd number?Marlowe
C
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>
Cletus answered 26/3, 2018 at 12:38 Comment(0)
F
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>';
}
Forgo answered 26/3, 2018 at 12:39 Comment(0)
D
0

For information about possible solutions and namings - you can use splitEvery method from Ramda

Doggett answered 7/2 at 18:53 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.