How to split a JavaScript array into halves or chunks

By

Split a JavaScript array in half, into fixed-size chunks, or into a chosen number of groups. Use slice() to keep the original array intact.

~~~

You can split an array into two halves, batches of a fixed size, or a chosen number of groups. Use slice() when you want to keep the original array.

Split an array in half

To divide an array in 2 parts, exactly in the middle, calculate the midpoint with Math.ceil() and use the Array instance slice() method twice:

const list = [1, 2, 3, 4, 5, 6]
const half = Math.ceil(list.length / 2)

const firstHalf = list.slice(0, half)
const secondHalf = list.slice(half)

firstHalf //[1, 2, 3]
secondHalf //[4, 5, 6]

slice() takes a start index and an end index, and returns a new array with the items between them. The end index is not included, which is why slice(0, 3) and slice(3) line up perfectly with no overlap and no gap.

When you call slice() with a single argument, it extracts from that index to the end of the array.

What happens with an odd number of items?

If the list contains an even number of items, the result is split with exactly half the items in each part.

If the number is odd, one half has to get the extra item. Math.ceil() rounds up, so the extra item goes to the first half:

const grades = [1, 2, 3, 4, 5]
const half = Math.ceil(grades.length / 2)

grades.slice(0, half) //[1, 2, 3]
grades.slice(half) //[4, 5]

If you’d rather have the extra item in the second half, use Math.floor() instead. With the same 5-item array you’d get [1, 2] and [3, 4, 5].

Does this change the original array?

No. slice() does not touch the array it’s called on. After the code above, list still contains all 6 items. You get two new arrays.

Be careful not to confuse slice() with splice(). The names are one letter apart but splice() mutates the array:

const list = [1, 2, 3, 4, 5, 6]
const firstHalf = list.splice(0, 3)

firstHalf //[1, 2, 3]
list //[4, 5, 6]

Here splice() removed the first 3 items from list and returned them. That can be exactly what you want, for example when you’re consuming a queue in batches. But if you used it by accident, the fix is to switch back to slice(), which leaves the original array intact.

If you want splice-style remove/insert behavior without mutating, use toSpliced(). It returns a new array and leaves the original alone:

const list = [1, 2, 3, 4, 5, 6]
const withoutFirstHalf = list.toSpliced(0, 3)

withoutFirstHalf //[4, 5, 6]
list //[1, 2, 3, 4, 5, 6]

Split into fixed-size chunks

If you want three items per batch, move through the array three items at a time:

const items = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
const chunkSize = 3
const chunks = []

for (let index = 0; index < items.length; index += chunkSize) {
  chunks.push(items.slice(index, index + chunkSize))
}

chunks //[[1, 2, 3], [4, 5, 6], [7, 8, 9], [10]]

The final chunk can be smaller. Use a positive integer for chunkSize.

You can also consume the original array with splice():

const items = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
const chunkSize = 3
const chunks = new Array(Math.ceil(items.length / chunkSize))
  .fill()
  .map(() => items.splice(0, chunkSize))

Here items ends up empty.

Split into a chosen number of groups

Sometimes you know how many groups you need. Divide the length by that number, then give the first groups any extra items:

const items = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
const groupCount = 3
const size = Math.floor(items.length / groupCount)
const extra = items.length % groupCount
let index = 0

const groups = Array.from({ length: groupCount }, (_, group) => {
  const end = index + size + (group < extra ? 1 : 0)
  const part = items.slice(index, end)
  index = end
  return part
})

groups //[[1, 2, 3, 4], [5, 6, 7], [8, 9, 10]]

Use a positive integer for groupCount. You get exactly that many groups, with sizes differing by at most one. If there are fewer items than groups, some groups are empty. Values such as 0, false, and empty strings stay in the result.

Want me to talk about your product? You can sponsor this site.

~~~

Related posts about js: