Have you ever wrote code similar with?:

boolean first = true;
StringBuilder result = new StringBuilder("");
 
for (Item item : collection) {
  if (!first) {
    result.append(", ");
  } else {
      first = false;
  }
 
  result.append(item);
}

I did, and I more often than not need this kind of code, and, as you do, I also dislike it.

It's ugly, hard to figure out what it does unless you stop a bit to think. This is why on my Germanium project I've picked a different strategy. I've created a class named OnceFirstIterator that contains the full "if first item state in it".

So no more if (first) then blah.

How does the end code look? I believe it's awesome, but you be the judge:

Simple list joining

OnceFirstIterator<String> comma = new OnceFirstIterator<String>("", ", ");
StringBuilder result = new StringBuilder("");
 
for (Item item : collection) {
  result.append(comma.next())
    .append(item);
}

or

Query path processing

OnceFirstIterator<String> parameterJoiner = new OnceFirstIterator<String>("?", "&amp;");
StringBuilder queryPath = new StringBuilder("");
 
for (Item queryItem : queryParameters) {
  result.append(parameterJoiner.next())
    .append(queryItem);
}

or

Basic SQL building

OnceFirstIterator<String> whereKeyword = new OnceFirstIterator<String>(" where ", " and ");
OnceFirstIterator<String> orderByKeyword = new OnceFirstIterator<String>(" order by ", ", ");
StringBuilder sql = new StringBuilder(...);
 
for (WhereClause whereClause : whereClauses) {
  sql.append(whereKeyword.next())
    .append(whereClause);
}
for (OrderByClause orderByClause : orderByClauses) {
  sql.append(orderByKeyword.next())
    .append(orderByClause);
}

So what are you waiting? Here is also a JavaScript implementation:

var onceMany = function(once, many) {
    var firstGenerated = false;
    return {
        next : function() {
            if (firstGenerated) {
                return many;
            } else {
                firstGenerated = true;
                return once;
            }
        }
    }
};

and some small JSON encoding using it:

    result = "{ ";
    var comma = onceMany("", ", ");
    for (var key in object) {
        result += comma.next() + "'" + key.replace(/'/g, "\\'") + "' : " +  jsonStringify(object[key]);
    }
    result += "}";
 

Twitter

putraxor
putraxor In order to understand recursion, one must first understand recursion. (Anonymous)

4 days ago via Twitter for Android • 5 retweets

bmst
bmst Seeing that i read about #vim amazon recommends me to read a book on #tmux. #allislostnow

4 days ago via Twitter for Android

bmst
bmst Vimscript: Where "true" is False, and "false" is Still False. ciplogic.com/index.php/blog…

6 days ago via Twitter for Websites

Germanium

The one to rule them all. The browsers that is.

SharpKnight

SharpKnight is an Android chess game.

MagicGroup

MagicGroup is an eclipse plugin.

Go to top