1

I have several BitArrays that will need to be merged to into 48 byte structure.

BitArray a1 = new (3);
BitArray a2 = new (11);
BitArray a3 = new (14);
//And so on

//Do bit manipulation, etc with the individual Arrays.

Ultimately, I want appended all the together and return a byte[] so I can send them out via UDP. I was thinking of keeping them in an array / list of just iterate thru them and dump them into an ulong - > byte[]

Azriel H
  • 45
  • 4
  • if you need special grouping, you have to precise how you would to group your BitArray to build 6 bytes of 8 bits or another type of building – Frenchy May 05 '23 at 06:52
  • Just some considerations: Is the data inteded to be sent / received _much_ more frequently than operated on (calculations / modifications / read-write-access) or is the data by far more "used" than transmitted? **If** you send it _much_ more often than you operate on it, you may want to consider choosing a byte-format to begin with and map access/modification operations around that. That way you avoid highly frequent conversions which _may_ (or may not) accumulate runtime/memory. – Fildor May 05 '23 at 07:59
  • @Fildor The data is a header protocol. I need to append this header to every message that gets sent out, frequency varies, but no faster than 1hz. Also all messages received will have this header, so I will need to decode the incoming byte[] into each a1. You think I am better off using byte shifting operations? – Azriel H May 05 '23 at 14:30

1 Answers1

4

According to this, there isn't really a better way to concatenate two BitArrays than just "doing it step by step" - make a bool[] for the result, copy each BitArray into there, and then make a new BitArray from the bool[].

BitArray ConcatenateAll(params BitArray[] arrays) {
    var bools = new bool[arrays.Sum(a => a.Count)];
    var index = 0;
    foreach (var array in arrays) {
        array.CopyTo(bools, index);
        index += array.Count;
    }
    return new BitArray(bools);
}

Since you want a byte[], you can do:

var bitArray = ConcatenateAll(bitArr1, bitArr2, ...);
var bytes = new byte[48];
bitArray.CopyTo(bytes, 0);

Note that you can also convert the bool[] directly into a byte[] by bit operations if performance is important, like in this answer.

Sweeper
  • 213,210
  • 22
  • 193
  • 313
  • @wohlstad Ah I see. The alternative would be to do some bit shifting and ANDing, in order to turn `bool[]` into a `byte[]` like [this](https://stackoverflow.com/a/24322811/5133585). – Sweeper May 05 '23 at 07:15
  • I thought simple copies into a `byte[]` will do (like in my posted answer). Am I wrong ? – wohlstad May 05 '23 at 07:16
  • @wohlstad I don't think that works. The second argument for `CopyTo` refers to an index of the destination array. This means you can't copy to a position *inside a byte*. I don't think the OP wants all the bit arrays to be aligned at byte boundaries. That's how I understand the word "appended" in the question. – Sweeper May 05 '23 at 07:19
  • You are absolutely right. +1. It was my mistake (and I deleted my answer). – wohlstad May 05 '23 at 07:21
  • 1
    I was wondering if OP shouldn't keep the data in a transmissible datastructure (`byte[]`) to begin with and taylor access / modification operations around that? - Unfortunately that's not an answer to the question but maybe a solution to the _problem_? – Fildor May 05 '23 at 08:02
  • Could use `int[]` or `byte[]` arrays also, see the docs https://learn.microsoft.com/en-us/dotnet/api/system.collections.bitarray.copyto?view=net-8.0#remarks but you would need whole 8- or 32-bit boundaries in each original `BitArray` – Charlieface May 05 '23 at 11:06