Home > database >  How to split and array into n arrays javascript
How to split and array into n arrays javascript

Time:07-06

let's say i have an array [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10] and i want to split it into n parts let's say 3 part so the result is supposed to be [ 1, 2, 3, 4 ],[ 4, 5, 6, 7],[ 8, 9, 10 ] but the code i have right now is or O(n*m) which is bad. Is there an optimal way of doing this?

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

const n = 3
const result = [[], [], []]

const wordsPerLine = Math.ceil(items.length / 3)

for (let line = 0; line < n; line  ) {
  for (let i = 0; i < wordsPerLine; i  ) {
     const value = items[i   line * wordsPerLine]
      if (!value) continue //avoid adding "undefined" values
      result[line].push(value)
  }
}

CodePudding user response:

Assuming the result needs to be [[ 1, 2, 3, 4 ], [ 5, 6, 7, 8 ], [ 9, 10 ]] you could use Array.reduce:

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

const parts = 3
const wordsPerLine = Math.ceil(items.length / parts)

const result = items.reduce((resultArray, item, index) => {
  const arrayIndex = Math.floor(index / wordsPerLine)
  if (!resultArray[arrayIndex]) {
    resultArray[arrayIndex] = [] // start a new array
  }
  resultArray[arrayIndex].push(item)
  return resultArray
}, [])

// result => [[ 1, 2, 3, 4 ], [ 5, 6, 7, 8 ], [ 9, 10 ]]

CodePudding user response:

We can write chunk(arr, size) using inductive reasoning -

  1. If arr.length is less than or equal to size, there are no more chunks to make. Return the singleton chunk of [ arr ]
  2. Otherwise (inductive) arr.length is greater than size, there is at least one chunk to make. Slice one chunk off the left of the array and prepend it to the result of the recursive sub-problem.

function chunk(arr, size) {
  if (arr.length <= size)
    return [ arr ]                                                 // 1
  else
    return [ arr.slice(0, size), ...chunk(arr.slice(size), size) ] // 2
}

const a =
  [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ]

const size =
  Math.ceil(a.length / 3)

const result =
  chunk(a, size)

console.log(
  JSON.stringify(result)
)

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

Visualize the evaluation -

chunk([0,1,2,3,4,5,6,7,8,9], 4)
[ [0,1,2,3], ...chunk([4,5,6,7,8,9], 4) ]
[ [0,1,2,3], ...[ [4,5,6,7], ...chunk([8,9], 4) ] ]
[ [0,1,2,3], ...[ [4,5,6,7], ...[ [8,9] ] ] ]
[ [0,1,2,3], ...[ [4,5,6,7], [8,9] ] ]
[ [0,1,2,3], [4,5,6,7], [8,9] ]

CodePudding user response:

To split up the array as evenly as possible:

function split_array(a, nparts) {
  const quot = Math.floor(a.length / nparts)
  const rem = a.length % nparts
  var parts = []
  for (var i = 0; i < nparts;   i) {
    const begin = i * quot   Math.min(rem, i)
    const end = begin   quot   (i < rem)
    parts.push(a.slice(begin, end))
  }
  return parts
}

var chunks = split_array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 3)
console.log(JSON.stringify(chunks))

Output:

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

The size of each part will never differ by more than 1.

CodePudding user response:

You could also use array.slice.

As the documentation reads, given the correct parameters, it will return a subset of your array, which you can then store into a new one.

For instance:

let n = 3;
let i = 0;
let resultArray = [];
let startArray = [1,2,3,4,5,6,7,8,9,10];
let arrayPortion = [];
const wordsPerLine = Math.ceil(startArray.length / n);

do {
  arrayPortion = startArray.slice(n*i, n*(i 1));
  resultArray.push(arrayPortion);
  i  ;
} while (arrayPortion.length==n && i*n<startArray.length); // Your end conditions.

This should work for any n.

CodePudding user response:

With O(n)

const items =  [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,11,12,13,14,15,16,17,18,19,20]
  const partitionSize = Math.ceil(items.length / 3)
  const result = [[], [], []]
  let resultIndex = 0, subArrayIndex = 0;
  for (let line = 0; line < items.length; line  ) {
     result[resultIndex].push(items[line])
     subArrayIndex  ;
     if(subArrayIndex == partitionSize) {
     resultIndex  ;
     subArrayIndex = 0;
     }
  }

Result:

 0: (7) [1, 2, 3, 4, 5, 6, 7]
1: (7) [8, 9, 10, 11, 12, 13, 14]
2: (6) [15, 16, 17, 18, 19, 20]
  • Related