I have this method and I want to know is there a practical and clean way to write this code shorter: This excersice was from a Dart Apprentice: Beyond the Basics book.
void main() {
final lyric = '[00:12.34]Row, row, row your boat';
final openBracketIndex = lyric.indexOf('[');
final colonIndex = lyric.indexOf(':');
final dotIndex = lyric.indexOf('.');
final endBracketIndex = lyric.indexOf(']');
final buffer = StringBuffer();
buffer.write('minutes: ');
buffer.write(lyric.substring(openBracketIndex + 1, colonIndex));
buffer.write('\n');
buffer.write('seconds: ');
buffer.write(lyric.substring(colonIndex + 1, dotIndex));
buffer.write('\n');
buffer.write('hundredths: ');
buffer.write(lyric.substring(dotIndex + 1, endBracketIndex));
buffer.write('\n');
buffer.write('lyrics: ');
buffer.write(lyric.substring(endBracketIndex + 1));
print(buffer);
}
The output is:
minutes: 00
seconds: 12
hundredths: 34
lyrics: Row, row, row your boat
You can make use of the cascade notation and writeln
method to shorten the code down to:
void main() {
final lyric = '[00:12.34]Row, row, row your boat';
final openBracketIndex = lyric.indexOf('[');
final colonIndex = lyric.indexOf(':');
final dotIndex = lyric.indexOf('.');
final endBracketIndex = lyric.indexOf(']');
final buffer = StringBuffer()
..write('minutes: ')
..writeln(lyric.substring(openBracketIndex + 1, colonIndex))
..write('seconds: ')
..writeln(lyric.substring(colonIndex + 1, dotIndex))
..write('hundredths: ')
..writeln(lyric.substring(dotIndex + 1, endBracketIndex))
..write('lyrics: ')
..write(lyric.substring(endBracketIndex + 1));
print(buffer);
}
We could also shorten it further if we allow us to build some of the string outside the StringBuilder
:
void main() {
final lyric = '[00:12.34]Row, row, row your boat';
final openBracketIndex = lyric.indexOf('[');
final colonIndex = lyric.indexOf(':');
final dotIndex = lyric.indexOf('.');
final endBracketIndex = lyric.indexOf(']');
final buffer = StringBuffer()
..writeln('minutes: ${lyric.substring(openBracketIndex + 1, colonIndex)}')
..writeln('seconds: ${lyric.substring(colonIndex + 1, dotIndex)}')
..writeln('hundredths: ${lyric.substring(dotIndex + 1, endBracketIndex)}')
..write('lyrics: ${lyric.substring(endBracketIndex + 1)}');
print(buffer);
}
A less pretty solution would be to skip the StringBuffer
and instead use a multi-line string as kind of a template:
void main() {
final lyric = '[00:12.34]Row, row, row your boat';
final openBracketIndex = lyric.indexOf('[');
final colonIndex = lyric.indexOf(':');
final dotIndex = lyric.indexOf('.');
final endBracketIndex = lyric.indexOf(']');
final string = '''
minutes: ${lyric.substring(openBracketIndex + 1, colonIndex)}
seconds: ${lyric.substring(colonIndex + 1, dotIndex)}
hundredths: ${lyric.substring(dotIndex + 1, endBracketIndex)}
lyrics: ${lyric.substring(endBracketIndex + 1)}
''';
print(string);
}