You are going to want to create a binary tree.
For each record you will follow a specific path through the binary tree.
When you hit the bottom, the tree element will have a single array of strings that you will concat with a single call.
Each tree node looks like this:
{
var str;
var strings;
var left, right;
}
You will populate the tree in two steps.
First time through, at each level you put in the string for that level.
root
left Node {str: 'Custom BA'} right Node {str: ''}
left Node {str: 'Custom Web Sim'} right Node {str: ''} left Node {str: 'Custom Web Sim'} right Node {str: ''}
Second time through, at each level, you will put in the agglomerated array for that level.
root
left Node {strs: 'Custom BA'} right Node {strings: []}
left Node {strings: ['Custom BA', 'Custom Web Sim']} right Node {strings: ['Custom BA']} left Node {strings: ['Custom Web Sim']} right Node {strings: []}
Now, once the array is populated, given any record, you traverse through the tree to the bottom. At each level, if the given field is 'true' you go left, otherwise you go right.
You are basically updating a single node variable to the current node as you go through.
Once at the bottom, you call:
products.concat(node.strings)
Why is this faster you ask? Because instead of doing 100 pushes per record, you do 1 concat per record.
Traversing the tree is no slower than the series of if statements you have already, you are just updating a single node variable rather than doing the push with each 'if' statement.
With a small number of records, this may take longer, due to the time taken to populate the tree. But as the record count gets larger, this will be much faster.
The tree will become large, 2 to the power of the number of fields, which for 100 fields is extremely large. So, you might wish to divide this into several trees which are 20 fields per tree (2 to the 20 is about a few megabytes per tree). And then you just traverse each tree individually in sequence.
One other optimization is to skip step 2 of populating the tree, and instead populate as you go along. If you traverse the tree for a record and see at the final node that the "strings" array is not populated, you repeat the same path and populate it.