How to Split a Long Array into Smaller Arrays, with JavaScript

How to split a long array into smaller arrays, with JavaScript

Don't use jquery...use plain javascript

var a = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15];

var b = a.splice(0,10);

//a is now [11,12,13,14,15];
//b is now [1,2,3,4,5,6,7,8,9,10];

You could loop this to get the behavior you want.

var a = YOUR_ARRAY;
while(a.length) {
console.log(a.splice(0,10));
}

This would give you 10 elements at a time...if you have say 15 elements, you would get 1-10, the 11-15 as you wanted.

Split array into chunks

The array.slice() method can extract a slice from the beginning, middle, or end of an array for whatever purposes you require, without changing the original array.

const chunkSize = 10;
for (let i = 0; i < array.length; i += chunkSize) {
const chunk = array.slice(i, i + chunkSize);
// do whatever
}

The last chunk may be smaller than chunkSize. For example when given an array of 12 elements the first chunk will have 10 elements, the second chunk only has 2.

Note that a chunkSize of 0 will cause an infinite loop.

Splitting array into multiple arrays

You can use map here to take those individual values and return them to a new array as arrays, just by wrapping them in braces.

let arrays = ['cat', 'apple', 'frog'];
console.log(JSON.stringify(arrays));

let final = arrays.map(m=>{return [m]});
console.log(JSON.stringify(final));

How to split an array into smaller arrays every time a specific value appears JavaScript?

You could iterate splitIndex and slice the array until this index.

const
data = ['abc', 'xyz', 123, 'split', 'efg', 'hij', 456, 'split'],
splitIndex = [3, 7],
result = [];

let i = 0;

for (const j of splitIndex) {
result.push(data.slice(i, j));
i = j + 1;
}

console.log(result);

Split an array into smaller chunks of arrays with the length provided by size. Need explanation for solution with modulo

Instead of using your (definitely more efficient, and also clearer) approach of taking consecutive slices, this takes the array item by item, storing the next group to be added in a temporary array. The test is basically asking (with a weird negative test) "Is this index not the last one in the group?" If that condition is true, and we're not on the last one for the current group, we simply add to the temporary group. If it's false, and we are on the last one, we add to the temporary group, add the temporary group to our output and create a new temporary group.

With a little refactoring, we can make this cleaner, perhaps something like this:

function chunkArrayInGroups(arr, size) {
const result = []
let temp = []

for (let a = 0; a < arr .length; a ++) {
temp .push (arr [a])
if (a % size === size - 1) {
result .push (temp)
temp = []
}
}

if (temp .length > 0) result .push (temp)

return result
}

But this holds no advantages over your approach, and is definitely less efficient. So I wouldn't consider it.

Here's an alternative that is to my mind cleaner, but also less efficient than yours:

const chunk = (xs, n) => xs .length <= n 
? [[...xs]]
: [xs .slice (0, n)] .concat (chunk (xs .slice (n), n))

This one grabs the first group by slicing it from the beginning of the array, and concatenates the results of recursively calling itself with the remainder of the array. The recursion ends when there are at most n elements remaining, and then we return an array containing only a copy of our input array ([[...x]]). We make the copy because all the other results are copies and not references, and it's better to be consistent.

This is similar to your approach in terms of number of slices and tests, but because of the recursive nature, it will fail for very large arrays and the repeated calls will make it somewhat less efficient. I'm often willing to take that tradeoff for cleaner code, myself, but YMMV.

Randomly split sorted array into smaller sorted arrays

Create n smaller arrays and an array of n indices. There is one index for each of the small arrays; they are all initialized to zero. Iterate over the large sorted array, at each step choosing one of the small arrays to put the value into. If the small array is already 'full' (its index is already equal to the length of the array), pick the next small array that is not yet full. Insert the value from the large array into the small array at the current value of its index, and then increment the index.

This will require a fast random number generator and perhaps a clever way of taking the completed subarrays out of the rotation, but it is linear in the large sorted array and requires no sorting.

In Java a two-dimensional array is an array of arrays, and we can leverage that to alter which subarrays each row is pointing to on the fly. The idea here is that subarrays is an array containing all the subarrays, and the references to them never change, but candidate starts out with references to all of them and gradually adjusts itself so that only the arrays that are still not full are referenced.

int[][] splitSorted(int[] array, int n) {
if (array.length % n != 0) {
throw new IllegalArgumentException(
n + " does not divide " + array.length + " evenly");
}
int size = array.length / n; // size of each subarray
int[][] subarrays = new int[n][size];
int[][] candidate = Arrays.copyOf(subarrays, subarrays.length);
int[] index = new int[n];

Random rand = new Random();
for (int i : array) {
int which = rand.nextInt(n);
candidate[which][index[which]] = i; // insert into a subarray
++index[which];
if (index[which] == size) { // one has maxed out
--n; // remove it from consideration
candidate[which] = candidate[n];
index[which] = index[n];
}
}
return subarrays;
}

When an array is full, we swap the one at the end of candidate into its place, so that the first rows contain the ones we're still trying to fill. Note that candidate completely loses track of the filled arrays. That's fine because they're still referenced by subarrays, which never changes. (We avoid having it alias candidate by taking a shallow copy with Arrays::copyOf when we create candidate.) We also have to swap the index for the array we're swapping.

Note also that the on the two lines that do the swap, which and n could be identical. An if could avoid setting them in this case, but setting them is redundant, so I prefer to keep the code simpler. n is decremented so the next time around the loop, we will pick a random number in a smaller range; only arrays that still need to be filled are considered. Finally, we return an array of all the filled subarrays.

It should be clear, but I will just underscore that because we put each value from the original large sorted array into one and only one subarray, and because we put them there in order, that the uniqueness and sorted constraints of the original array will be maintained on the subarrays.



Related Topics



Leave a reply



Submit