How do I reverse a String in Dart?

22,881

Solution 1

The question is not well defined. Reversing arbitrary strings does not make sense and will lead to broken output. The first (surmountable) obstacle is Utf-16. Dart strings are encoded as Utf-16 and reversing just the code-units leads to invalid strings:

var input = "Music \u{1d11e} for the win"; // Music 𝄞 for the win
print(input.split('').reversed.join()); // niw eht rof

The split function explicitly warns against this problem (with an example):

Splitting with an empty string pattern ('') splits at UTF-16 code unit boundaries and not at rune boundaries[.]

There is an easy fix for this: instead of reversing the individual code-units one can reverse the runes:

var input = "Music \u{1d11e} for the win"; // Music 𝄞 for the win
print(new String.fromCharCodes(input.runes.toList().reversed)); // niw eht rof 𝄞 cisuM

But that's not all. Runes, too, can have a specific order. This second obstacle is much harder to solve. A simple example:

var input =  'Ame\u{301}lie'; // Amélie
print(new String.fromCharCodes(input.runes.toList().reversed)); // eiĺemA

Note that the accent is on the wrong character.

There are probably other languages that are even more sensitive to the order of individual runes.

If the input has severe restrictions (for example being Ascii, or Iso Latin 1) then reversing strings is technically possible. However, I haven't yet seen a single use-case where this operation made sense.

Using this question as example for showing that strings have List-like operations is not a good idea, either. Except for few use-cases, strings have to be treated with respect to a specific language, and with highly complex methods that have language-specific knowledge.

In particular native English speakers have to pay attention: strings can rarely be handled as if they were lists of single characters. In almost every other language this will lead to buggy programs. (And don't get me started on toLowerCase and toUpperCase ...).

Solution 2

Here's one way to reverse an ASCII String in Dart:

input.split('').reversed.join('');
  1. split the string on every character, creating an List
  2. generate an iterator that reverses a list
  3. join the list (creating a new string)

Note: this is not necessarily the fastest way to reverse a string. See other answers for alternatives.

Note: this does not properly handle all unicode strings.

Solution 3

I've made a small benchmark for a few different alternatives:

String reverse0(String s) {
  return s.split('').reversed.join('');
}

String reverse1(String s) {
  var sb = new StringBuffer();
  for(var i = s.length - 1; i >= 0; --i) {
    sb.write(s[i]);
  }
  return sb.toString();
}

String reverse2(String s) {
  return new String.fromCharCodes(s.codeUnits.reversed);
}

String reverse3(String s) {
  var sb = new StringBuffer();
  for(var i = s.length - 1; i >= 0; --i) {
    sb.writeCharCode(s.codeUnitAt(i));
  }
  return sb.toString();
}

String reverse4(String s) {
  var sb = new StringBuffer();

  var i = s.length - 1;

  while (i >= 3) {
    sb.writeCharCode(s.codeUnitAt(i-0));
    sb.writeCharCode(s.codeUnitAt(i-1));
    sb.writeCharCode(s.codeUnitAt(i-2));
    sb.writeCharCode(s.codeUnitAt(i-3));
    i -= 4;
  }

  while (i >= 0) {
    sb.writeCharCode(s.codeUnitAt(i));
    i -= 1;
  }

  return sb.toString();
}

String reverse5(String s) {
  var length = s.length;
  var charCodes = new List(length);
  for(var index = 0; index < length; index++) {
    charCodes[index] = s.codeUnitAt(length - index - 1);
  }

  return new String.fromCharCodes(charCodes);
}
main() {
  var s = "Lorem Ipsum is simply dummy text of the printing and typesetting industry.";

  time('reverse0', () => reverse0(s));
  time('reverse1', () => reverse1(s));
  time('reverse2', () => reverse2(s));
  time('reverse3', () => reverse3(s));
  time('reverse4', () => reverse4(s));
  time('reverse5', () => reverse5(s));
}

Here is the result:

reverse0: => 331,394 ops/sec (3 us) stdev(0.01363)
reverse1: => 346,822 ops/sec (3 us) stdev(0.00885)
reverse2: => 490,821 ops/sec (2 us) stdev(0.0338)
reverse3: => 873,636 ops/sec (1 us) stdev(0.03972)
reverse4: => 893,953 ops/sec (1 us) stdev(0.04089)
reverse5: => 2,624,282 ops/sec (0 us) stdev(0.11828)

Solution 4

Try this function

String reverse(String s) {
  var chars = s.splitChars();
  var len   = s.length - 1;
  var i     = 0;

  while (i < len) {
    var tmp = chars[i];
    chars[i] = chars[len];
    chars[len] = tmp;
    i++;
    len--;
  }

  return Strings.concatAll(chars);
}

void main() {
  var s = "Hello , world";
  print(s);
  print(reverse(s));
}

(or)

String reverse(String s) {
  StringBuffer sb=new StringBuffer();
  for(int i=s.length-1;i>=0;i--) {
    sb.add(s[i]);
  }
  return sb.toString();
}

main() {
  print(reverse('Hello , world'));
}

Solution 5

There are many ways to reverse a string in Dart, some of them are given below.

Use split and join:

String reverseStringUsingSplit(String input) {
  var chars = input.split('');
  return chars.reversed.join();
}



Use runes:

String reverseStringUsingRunes(String input) {
  var chars = input.runes.toList();

  return String.fromCharCodes(chars.reversed);
}



Use codeUnits:

String reverseStringUsingCodeUnits(String input) {
  return String.fromCharCodes(input.codeUnits.reversed);
}

You can simply use all methods like this

void main() {
  var coflutter = 'Coflutter';

  print(reverseStringUsingSplit(coflutter));
  print(reverseStringUsingRunes(coflutter));
  print(reverseStringUsingCodeUnits(coflutter));
}

The output of all 3 methods will be

rettulfoC
rettulfoC
rettulfoC

Ref: https://coflutter.com/dart-how-to-reverse-a-string/

Share:
22,881
Seth Ladd
Author by

Seth Ladd

Product Manager at Google.

Updated on January 17, 2022

Comments

  • Seth Ladd
    Seth Ladd over 2 years

    I have a String, and I would like to reverse it. For example, I am writing an AngularDart filter that reverses a string. It's just for demonstration purposes, but it made me wonder how I would reverse a string.

    Example:

    Hello, world
    

    should turn into:

    dlrow ,olleH
    

    I should also consider strings with Unicode characters. For example: 'Ame\u{301}lie'

    What's an easy way to reverse a string, even if it has?