How to format an interploated String

DartFlutter

Dart Problem Overview


I need format string like "Send %d seconds ago", "Harry like %s", "I think %1$s like %2$s". These can be implemented in Android, but i don't how to implement in Dart of Flutter.

Dart Solutions


Solution 1 - Dart

Dart supports string interpolation

var seconds = 5;
print("Send $seconds seconds ago");

var harryLikes = 'Silvia';
var otherName = 'Erik';
var otherLikes = 'Chess';
print("Harry like $harryLikes");
print("I think $otherName like $otherLikes");

Also more complex expressions can be embedded with ${...}

print('Calc 3 + 5 = ${3 + 5}');

The number types and the intl package provide more methods to format numbers and dates.

See for example:

Solution 2 - Dart

Add the following to your pubspec.yaml

dependencies:
  sprintf: "^5.0.0"

then run pub install.

Next, import dart-sprintf:

import 'package:sprintf/sprintf.dart';

Example #

import 'package:sprintf/sprintf.dart';

void main() {
     double seconds = 5.0;
       String name = 'Dilki';
       List<String> pets = ['Cats', 'Dogs'];

       String sentence1 = sprintf('Sends %2.2f seconds ago.', [seconds]);
       String sentence2 = sprintf('Harry likes %s, I think %s likes %s.', [pets[0], name, pets[1]]);

       print(sentence1);
       print(sentence2);
}

Output

Sends 5.00 seconds ago.

Harry likes Cats, I think Dilki likes Dogs.

Source: https://pub.dartlang.org/packages/sprintf

Solution 3 - Dart

Like already stated, I also use the sprintf package but along with a handy extension of the String class.

So after adding the package dependency sprintf: "^4.0.0" to your dependencies list in pubspecs.yaml, create a new Dart-file containing the extension for the Spring class contributing a format method like this:

extension StringFormatExtension on String {
  String format(var arguments) => sprintf(this, arguments);
}

Now after you import the dart file containing the StringFormatExtension extension, you can type something like:

String myFormattedString = 'Hello %s!'.format('world');

Feels like in Java (where I come from).

Solution 4 - Dart

If you want String interpolation similar to Android (Today is %1$ and tomorrow is %2$), you can create a top level function, or an extension that can do something similar. In this instance I keep it similar to Android strings as I'm currently porting an Android app (Interpolatation formatting starts with 1 rather than 0)

Top Level Function

String interpolate(String string, List<String> params) {

  String result = string;
  for (int i = 1; i < params.length + 1; i++) {
    result = result.replaceAll('%${i}\$', params[i-1]);
  }

  return result;
}

You can then call interpolate(STRING_TO_INTERPOLATE, LIST_OF_STRINGS) and you string would be interpolated.

Extensions

You can create an extension function that does something similarish to Android String.format()

extension StringExtension on String {
    String format(List<String> params) => interpolate(this, params);
}

This would then allow you to call text.format(placeHolders)

Testing

Couple of tests for proof of concent:-

test('String.format extension works', () {
    // Given
    const String text = 'Today is %1\$ and tomorrow is %2\$';
    final List<String> placeHolders = List<String>()..add('Monday')..add('Tuesday');
    const String expected = 'Today is Monday and tomorrow is Tuesday';

    // When
    final String actual = text.format(placeHolders);

    // Then
    expect(actual, expected);
  });

Solution 5 - Dart

I did it the old fashioned way

String url = "https://server.com/users/:id:/view";
print(url.replaceAll(":id:", "69");

Solution 6 - Dart

you could also have something simple like this:

  • Usage
interpolate('Hello {#}{#}, cool {#}',['world','!','?']);
// Hello world!, cool ?
  • Function
  static const needleRegex = r'{#}';
  static const needle = '{#}';
  static final RegExp exp = new RegExp(needleRegex);

  static String interpolate(String string, List l) {
    Iterable<RegExpMatch> matches = exp.allMatches(string);

    assert(l.length == matches.length);

    var i = -1;
    return string.replaceAllMapped(exp, (match) {
      print(match.group(0));
      i = i + 1;
      return '${l[i]}';
    });
  }

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionH3cView Question on Stackoverflow
Solution 1 - DartGünter ZöchbauerView Answer on Stackoverflow
Solution 2 - DartenadunView Answer on Stackoverflow
Solution 3 - DartMartin KerstenView Answer on Stackoverflow
Solution 4 - DartPhill WigginsView Answer on Stackoverflow
Solution 5 - DartSuperCodeView Answer on Stackoverflow
Solution 6 - DartTarek BView Answer on Stackoverflow