Notifications
Clear all

[Closed] Splitting bitarrays into smaller bitarrays

Does anyone have a fast function for splitting a bitarray into x sized smaller bitarrays?

eg:
A=#{1,3,7,10…15,18,20,25,56,58,60,70…80}

splitting ‘A’ into 10’s would generate something like

#{1,3,7,10…15,18,20}
#{25,56,58,60…67}
#{68…70,80}

Speed is of the essence here…

Thanks,

5 Replies

here’s my attempt, hopefully there’s an easier way to do this . any how, the splitbitray function takes 2 params, a bit array a and an integer x and splits the bit array at x intervals

fn splitbitray a  x = 
(
	st = timestamp()	
	b = #()
	k = 1
	initj = 0
	maxcount = a.count
	for i = x to maxcount by x do
	(
		if (finditem a i)!=0 do
		(
			b[k] = #{}
			for j = initj to (initj+x) do
			(				
				if (finditem a j)!=0 do
				(
					append b[k] j
				)
			)
			initj = i
			k+=1
		)
	)	
	for l=1 to b.count do
		print b[l]
	et = timestamp()
	format "took % miliseconds
" (et-st)
)
a=#{1,3,7,10..15,18,20,22,25,50,56,58,60,70..80}	

splitbitray a 10

cheers!

Hi, here is my version, it should be a little faster. Takes as input the bitarray and the dimension of new chunks.

function splitBitArray baInput iSpan =
(
    local baChunk = #{}
    local iCount = 0
    local abaOutput = #()

    for iIndex in baInput do
    (
        baChunk[iIndex] = true
        iCount += 1
        
        if (iCount == iSpan) do
        (
            append abaOutput baChunk
            baChunk = #{}
            iCount = 0
        )
    )

    if (not baChunk.isEmpty) do
        append abaOutput baChunk

    return abaOutput
)
  • Enrico

thanks guys, extremely helpful

Hornbergers was slightly faster on some giant bitarrays I tried, but duplicates bits between arrays, ie:

#(#{1…10}, #{10…20}, #{20…30}, #{30…40}, #{40…50}

Whereas SyncViewS gives the correct:
#(#{1…10}, #{11…20}, #{21…30}, #{31…40}, #{41…50}

If you have to deal with huge BitArray, there is another handy optimization to play: rather then appending small BitArrays to a single Array, which can become quite slow when it grows, there can be a cap to appending say 10 bitArrays to an Array, then other 10 to another one and so on, and perform as last passage the join of all Arrays containing BitArrays chunks. I hope this is clear. If I have a bunch of minutes, I’ll give it a try.

  • Enrico

sorry had a misconception before here’s the corrected code

fn splitbitray a  x = 
(
	st = timestamp()	
	a = a as array
	k = 1
	b = #()
	for i = 1 to (a.count) by x do
	(
		b[k] = #{}
		nextj = i+x-1 
		if nextj> a.count do
			nextj = a.count
		for j = i to (nextj) do
		(
			append b[k] a[j]
		)
		if (b[k].count>1) do
			k+=1
	)
	for l=1 to b.count do
		format "%" b[l]
	et = timestamp()
	format "
took % miliseconds
" (et-st)
)
a=#{1,3,7,10..15,18,20,25,56,58,60,70..80}	

splitbitray a 10

cheers!