Is there any simple way to concatenate two BitArray (C# .NET)?
Asked Answered
E

5

9

I have

var previous = new BitArray(new bool[]{true});
var current = new BitArray(new bool[]{false});

I want to concatenate them. I have already tried:

var next = new BitArray(previous.Count + current.Count);
var index = 0;
for(;index < previous.Count; index++)
    next[index] = previous[index];
var j = 0;
for(;index < next.Count; index++, j++)
    next[index] = current[j];
previous = current;

But it doesn't look like the best way to do it.

Eckenrode answered 5/2, 2009 at 23:45 Comment(0)
P
10

Unfortunately it looks like your method might be as good as it gets - if BitArray implemented IEnumerable<T> (instead of just IEnumerable) then we could use LINQ extension methods to make it a bit prettier.

If I were you, I'd wrap this up into an extension method on BitArray:

public static BitArray Prepend(this BitArray current, BitArray before) {
    var bools = new bool[current.Count + before.Count];
    before.CopyTo(bools, 0);
    current.CopyTo(bools, before.Count);
    return new BitArray(bools);
}

public static BitArray Append(this BitArray current, BitArray after) {
    var bools = new bool[current.Count + after.Count];
    current.CopyTo(bools, 0);
    after.CopyTo(bools, current.Count);
    return new BitArray(bools);
}
Phytogeography answered 5/2, 2009 at 23:56 Comment(1)
If you know that the first array contains an even multiple of 32 bits, you can optimize this significantly by using int arrays instead of bool arrays. CopyTo works with int[], bool[] and byte[]Lafreniere
M
6

One can do this with LINQ, after Cast<bool>() the bitarray 'becomes' IEnumerable<bool>:

var previous = new BitArray(new bool[] { true });
var current = new BitArray(new bool[] { false });

BitArray newBitArray = 
    new BitArray(previous.Cast<bool>().Concat(current.Cast<bool>()).ToArray());

I don't think this LINQ method will be fast.

Martinez answered 12/3, 2009 at 20:27 Comment(0)
N
2

The framework doesn't provide a nice way of doing this. You could create an array of bools that is large enough to store both BitArrays. Then use BitArray.CopyTo to copy each BitArray in the array of bools (you can specify where to start inserting the elements).

After this is done, create another BitArray with the constructor that accepts an array of bools.

A lot of work I know, but there doesn't seem to be another way. It's less code than your current method however.

Newmann answered 5/2, 2009 at 23:56 Comment(0)
H
0

Here is my LINQ implementation which does not include the overhead of having to allocate an array of bools:

var result = new BitArray(first.Count + second.Count);

var i = 0;
foreach (var value in first.Cast<bool>().Concat(second.Cast<bool>()))
{
    result[i++] = value;
}
Hsining answered 6/3, 2016 at 11:20 Comment(0)
D
-1

It is more efficient if you use int32 instead of bools because bitarray uses int32 internally.

public static BitArray Append(this BitArray current, BitArray after) {
    var ints = new int[(current.Count + after.Count) / 32];
    current.CopyTo(ints, 0);
    after.CopyTo(ints, current.Count / 32);
    return new BitArray(ints);
}

In Vb.net if anyone need it:

<Runtime.CompilerServices.Extension()> _
Public Function Append(ByVal current As BitArray, ByVal after As BitArray) As BitArray
    Dim ints = New Int32((current.Count + after.Count) \ 32 - 1) {}
    current.CopyTo(ints, 0)
    after.CopyTo(ints, current.Count \ 32)
    Return New BitArray(ints)
End Function
Docilu answered 23/7, 2013 at 15:51 Comment(2)
This code only works if both incoming bit arrays have lengths that are multiples of 32 - otherwise you get an out of bounds exception since the integer division by 32 rounds the result down, making 'ints' too short. Making 'ints' longer also isn't sufficient, since unless 'current' length is a multiple of 32, the appended array will leave unused bits in the middle, which is likely not what one wants.Innocent
Good idea, but as @KristianWedberg mentions this will only work under certain (rare) conditions.Romelda

© 2022 - 2024 — McMap. All rights reserved.