Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to transform a string of 0s and 1s into a boolean array

Tags:

arrays

c#

Basically, the title says what I'd like to do.

I have a string such as the following.

1 0 1 0 1
0 0 0 0 0
1 0 0 0 1
0 0 0 0 0
1 0 1 0 1

I'd like to convert this into a 2-dimensional boolean array (obviously, 0 -> false and 1 -> true). My current approach is removing non-linebreak-whitespace, then iterating through the lines of the string.

This leaves me with transforming a string such as 10101 into a boolean array of true, false, true, false, true. Now, I'm hoping that there are pre-existing methods to do this conversion - using Java, I'm pretty sure it could be done using the streams API, but unfortunately, I'm not that adept with C# yet.


Hence, my question: Are there existing methods to do this conversion in a compact way? Or do I have to manually iterate over the string and do a == 0/==1 comparison for each character?

like image 605
PixelMaster Avatar asked May 20 '18 21:05

PixelMaster


2 Answers

Single string

If you have a a string like "10101", you can use LINQ to convert it to a bit array.

string input = "10101";
bool[] flags = input.Select( c => c == '1' ).ToArray();

Array of strings

LINQ doesn't work so well with two-dimensional arrays, but it works fine with jagged arrays. If a bool[][] will do, this solution should work:

string[] input = { "10101","01010" };

bool[][] flags = input.Select
(
    s => s.Select
    ( 
        c => c == '1'
    )
    .ToArray()
)
.ToArray();
like image 157
John Wu Avatar answered Sep 22 '22 12:09

John Wu


Here's a relatively ugly "one-liner":

string input = "1 0 1 0 1\n0 0 0 0 0\n1 0 0 0 1\n0 0 0 0 0\n1 0 1 0 1";
bool[][] flags = input.Split(new[] { "\n" }, StringSplitOptions.None) // Split into lines, e.g. [ "1 0 1 0 1", "0 0 0 0 0" ]
                      .Select(line => line.Split(' ') // Split each line into array of "1"s or "0"s
                                          .Select(num => num == "1").ToArray()) // Project each line into boolean array
                      .ToArray(); // Get array of arrays

But here is an (arguably more readable) version that probably comes closer to what I suspect is your actual use case, e.g. reading a line from the user one at a time.

string input = "1 0 1 0 1\n0 0 0 0 0\n1 0 0 0 1\n0 0 0 0 0\n1 0 1 0 1";

List<bool[]> boolArrays = new List<bool[]>();

string[] lines = input.Split(new[] { "\n" }, StringSplitOptions.None);
foreach (string line in lines) // Could be a different loop that gets lines from the user, e.g. `do { var s = Console.ReadLine(); doMore(); } while (s != null);`
{
    string[] charsAsStrings = line.Split(' '); // TODO: Improve variable names
    bool[] arrayRow = charsAsStrings.Select(numString => numString == "1").ToArray(); // Parsing to int would be pointless
    boolArrays.Add(arrayRow);
}

bool[][] flags = list.ToArray();

As noted in the comments, you typically want to use Environment.NewLine rather than "\n". Note that we can't split by a string without providing an entire array -- though that can be solved with extension methods.

like image 22
Sinjai Avatar answered Sep 21 '22 12:09

Sinjai