2

I have searched in net but not getting exactly what I need. I have a bitarray of size 15,936. I need to divide this bit array into list of bitarrays , with each bit array having 32 bits(15936/32 = 498 bitarray list).

Not able to find exactly how to divide bitarray. Please do help.

Thanks,

1
  • You could always use an int[498]... Commented Dec 8, 2016 at 9:21

2 Answers 2

6

The first that you want 32-bit values makes this pretty easy, because you can copy it to an int[], then create one BitArray per int, passing the data by creating a single-element int array:

int[] values = new int[bigBitArray.Length / 32];
bigBitArray.CopyTo(values, 0);
var smallBitArrays = values.Select(v => new BitArray(new[] { v })).ToList();

Or more efficiently, reusing the same int[] for each iteration:

int[] values = new int[bigBitArray.Length / 32];
bigBitArray.CopyTo(values, 0);
// Reuse this on every iteration, to avoid creating more arrays than we need.
// Somewhat ugly, but more efficient.
int[] buffer = new int[1];
var smallBitArrays = values.Select(v =>
{ 
    buffer[0] = v; 
    return new BitArray(buffer))
}).ToList();

If those give you the bit arrays in the opposite order to what you expect, just call Array.Reverse(values) after the CopyTo call.

It's a pity that BitArray doesn't have a constructor taking an existing array, offset and count... that would make it significantly more efficient. (As would a "slice copy" operation, of course.)

A more general purpose option would be to create an extension method precisely for that "slice copy" part:

public static BitArray CopySlice(this BitArray source, int offset, int length)
{
    // Urgh: no CopyTo which only copies part of the BitArray
    BitArray ret = new BitArray(length);
    for (int i = 0; i < length; i++)
    {
         ret[i] = source[offset + i];
    }
    return ret;
}

Then:

var smallBitArrays = Enumerable
    .Range(0, bigBitArray.Length / 32)
    .Select(offset => bigBitArray.CopySlice(offset * 32, 32))
    .ToList();
Sign up to request clarification or add additional context in comments.

17 Comments

This won't work because the BitArray constructor with an int param does not initialize the BitArray, it sets its capacity.
@Sefe: Have you seen the fix? (Not sure why this got a second downvote after fixing, but hey...)
@Sefe: Appreciated. Ah well - downvotes seem to have been removed now anyway. This question has reminded me what an awful API BitArray has :(
That's why I'm using Array.Copy. Even with an API, this would be the most efficient way to slice a bit array (it's how it would work under the hood, except it wouldn't need the CopyTo).
@Sefe: Why do you believe Array.Copy is more efficient than just new int[] { v }? If you'd used the same byte array for each iteration, that would be more efficient - something I'll do in my version now.
|
2

You can copy your bit array into an array of bytes, split that array into chunks and create new bit arrays:

const int subArraySizeBits = 32;
const int subArraySizeBytes = subArraySizeBits / 8;
byte[] bitData = new byte[myBitArray.Length / subArraySizeBytes];
myBitArray.CopyTo(bitData, 0);
List<BitArray> result = new List<BitArray>();
for (int index = 0; index < bitData.Length; index += subArraySizeBytes) {
    byte[] subData = new byte[subArraySizeBytes];
    Array.Copy(bitData, index * subArraySizeBytes, subData, 0, subArraySizeBytes);
    result.Add(new BitArray(subData));
}

2 Comments

hi, thanks for the response, I also thought to do in this way. yours is a good answer too.
I thought this was a good solution so upvoted it, but it doesn't work. You can't use myBitArray.CopyTo(bitData, 0); into a smaller array.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.