Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Split array into pieces of X length

Currently I have an array of size N. I'm trying to copy every X amount of bytes from the array.

Example if the array is size 10 and I want arrays of size 3. I'd copy the first 3 elements then the next 3 and the last 1.

Currently I'm using the following algorithm:

int I = 0;
int sub = bytes.length;
int counter = 0;
for (I = 0; I < bytes.length; ++I) {
    if (I % 3 == 0 && I != 0) {
       NewArray[counter] = Arrays.copyOfRange(bytes, I - 3, I));
        sub -= 3;
        ++counter;
    }
}

NewArray[counter] = Arrays.copyOfRange(bytes, I - sub, I)); //Copy remainder.

Is there a more efficient or a more decent way of doing the what I want? This algorithm looks pretty bad =l

Any ideas how I can improve it or at least a hint?

like image 644
Brandon Avatar asked Oct 08 '13 01:10

Brandon


People also ask

How do you split an array in chunks?

Splitting the Array Into Even Chunks Using slice() Method The easiest way to extract a chunk of an array, or rather, to slice it up, is the slice() method: slice(start, end) - Returns a part of the invoked array, between the start and end indices.

How do you break an array into 3 parts?

An efficient solution is to first find the sum S of all array elements. Check if this sum is divisible by 3 or not. This is because if sum is not divisible then the sum cannot be split in three equal sum sets. If there are three contiguous subarrays with equal sum, then sum of each subarray is S/3.


2 Answers

What about this:

int x = 3;  // chunk size
int len = bytes.length;
int counter = 0;

for (int i = 0; i < len - x + 1; i += x)
    newArray[counter++] = Arrays.copyOfRange(bytes, i, i + x);

if (len % x != 0)
    newArray[counter] = Arrays.copyOfRange(bytes, len - len % x, len);
like image 171
arshajii Avatar answered Oct 07 '22 00:10

arshajii


Here's a convenient method that converts a byte[] to an array of byte[]'s. So, the result is a byte[][].

public byte[][] splitBytes(final byte[] data, final int chunkSize)
{
  final int length = data.length;
  final byte[][] dest = new byte[(length + chunkSize - 1)/chunkSize][];
  int destIndex = 0;
  int stopIndex = 0;

  for (int startIndex = 0; startIndex + chunkSize <= length; startIndex += chunkSize)
  {
    stopIndex += chunkSize;
    dest[destIndex++] = Arrays.copyOfRange(data, startIndex, stopIndex);
  }

  if (stopIndex < length)
    dest[destIndex] = Arrays.copyOfRange(data, stopIndex, length);

  return dest;
}

Some advantages compared to the previous best answer:

  1. The for condition uses a <= which makes more sense than < ... + 1.
  2. Putting the stop-index in a temporary field reduces the number of calculations in the last if block.

(Unit tested)

like image 33
bvdb Avatar answered Oct 07 '22 00:10

bvdb