Building string programatically and dealing with trailing or leading boolean operators
-
05-07-2019 - |
Question
I am using Lucene in an application. As such I have a form that lets users build a query by selecting what they want to search from dropdowns. Once a user submits, I build the query and it comes down to something like this:
var formedQuery= string.Empty;
foreach(var field in fields)
{
if (field.name != 'condition so you never know which field from fields will be 1st')
formedQuery += " AND" + field.name + ":" field.value;
}
Now the problem with this is that the statement will begin with ' AND'
Now I usually finish with:
formedQuery = formedQuery.Substring(4) //Trim the first 4 characters
Would fellow programmers usually prefer to do:
var formedQuery= string.Empty;
var i = false;
foreach(var field in fields)
{
if (false &&
field.name != 'condition so you never know which field from fields will be 1st')
{
formedQuery += " AND" + field.name + ":" field.value;
i = true;
}
else
formedQuery += " " + field.name + ":" field.value;
}
Is there another technique people like to use for this sort of thing I am not thinking of? I prefer the former.
Solution
There are two other solutions I use, depending a little on the language. The first is similar to your second one, but just changes the "first-field" check.
var formedQuery = string.Empty;
var and = string.Empty;
foreach(var field in fields)
{
if (field.name != 'condition so you never know which field from fields will be 1st')
{
formedQuery += and + field.name + ":" field.value;
and = " AND";
}
}
But the solution I usually use involves an ordered list. Assuming I can extend your example code in any way that looks sensible:
var formedQuery = list.Empty;
foreach(var field in fields)
{
if (field.name != 'condition so you never know which field from fields will be 1st')
{
formedQuery.push(field.name + ":" field.value);
}
}
formedQuery = formedQuery.join(" AND ");
This also has the advantage of not making lots of unnecessary string copies as your assemble the string (in some languages, this is expensive).
OTHER TIPS
I have always used the former. Mostly because it looks cleaner to me.
Another approach:
query = first_field_name
for every other field besides first:
query = " AND " + field_name