26 March, 2017

Split Array into smaller arrays - Scripting

Have you had a case when you had a long list of things and you wanted to split it up? Like a long shopping list which you really didn't want to tackle alone. Or you have a long list of IP addresses or host names, or object in Active Directory...whatever. And you want to split the long list to many smaller lists to run things in parallel or to stagger the running of a script (make sure you only run a script on a smaller batch at a time instead of running it on the full list).

So let's split a long list of host names to 6 pieces. You can do this in many ways, but I use this oneliner: 

$NumberOfArrays = 6; $NewArrays = @{}; $i = 0;  gc c:\hostlist.txt | %{$NewArrays[$i % $NumberOfArrays] += @($_); $i++}; $NewArrays


It uses a few tricks.

The first one is the modulus operator (%) which spits out the reminder part when you divide two integers. That will mean if you do a mod operation on a running number (from 1 to the max count of the list) with the number you want to split the list to, it will repeat a sequence of numbers. From 0 until it reaches the number one less than the number we are dividing by. Like this:
Lift of index numbers we can use for splitting the list


The second trick is that this generated repeating sequence of numbers are used as index (or keys) of a hash table. Each key in the hash table has a value, in this case the values of keys will the split list of hosts. The hash table here is $NewArrays which has the arrays of the smaller lists:
The list of smaller lists (arrays) in a hash table

Note the 'Name' column which is the list of keys.

To pull each list one by one, you can address each key with the .Item parameterized property.


Add caption
Or like this:

0..5 | %{$NewArrays.item($_)}


t