Iterate over string letter by letter

2,140 views
Skip to first unread message

firen

unread,
Mar 22, 2013, 8:52:17 PM3/22/13
to mi...@dartlang.org
Hi,
As topic says, I would like to create an iterator which will iterate over letters in String.
Is there any class for this? Or should I implement my own?
I would like to avoid to use [] operator.

Regards,
  Adam

John Messerly

unread,
Mar 22, 2013, 9:17:31 PM3/22/13
to General Dart Discussion, Alan Knight
Funny, I was just talking to Alan about this. Alan, did you have a helper somewhere for doing this?


--
Consider asking HOWTO questions at Stack Overflow: http://stackoverflow.com/tags/dart
 
 

chl

unread,
Mar 22, 2013, 9:48:47 PM3/22/13
to mi...@dartlang.org


Iterator<String> getStringIterator(String s) =>
  s
.runes.map((r) => new String.fromCharCode(r)).iterator;

Personally, i would rather return a list, as opposed to an iterator.

Lasse R.H. Nielsen

unread,
Mar 22, 2013, 9:49:00 PM3/22/13
to mi...@dartlang.org
There is no standard class that directly iterates over substrings of a string.
The "codeUnits" getter gives you an Iterable that iterates over the numerical UTF-16 code units of the string (the values you get from .codeUnitAt(i) for i = 0 to length - 1.
The "runes" getter gives you an Iterable that iterates over the code points of the string, with surrogate pairs combined. Its iterator can also be used to get the corresponding substrings.

/L



--
Consider asking HOWTO questions at Stack Overflow: http://stackoverflow.com/tags/dart
 
 



--
Lasse R.H. Nielsen - l...@google.com  
'Faith without judgement merely degrades the spirit divine'
Google Denmark ApS - Frederiksborggade 20B, 1 sal - 1360 København K - Denmark - CVR nr. 28 86 69 84

Alex Tatumizer

unread,
Mar 23, 2013, 3:31:03 PM3/23/13
to mi...@dartlang.org
FYI: performance of the following iterator is about 400K chars/sec.
String s=.... 
for (var t in s.runes) {var c=new String.fromCharCode(t);};

If you iterate over runes as ints (not as 1-char Strings) performance is 8M chars/sec
for (var t in s.runes) {var c=t;};

For reasons I don't understand, performance of this iterator is WORSE than runes : 4M chars/sec
for (var t in s.codeUnits) {var c=t;};   

However, if you write it like this:
var codes=s.codeUnits;
var c;
for (int i=0; i<codes.length; i++)
   c=codes[i];
performance is 30M chars/sec 

Loop over runes is  3-4M chars/sec 
var codes=s.runes.toList();
for (int i=0; i<codes.length; i++)
  c=codes[i];

Maybe, after better optimization is implemented in dart, the difference won't be that large, but for now, it's significant.
400K chars/sec is probably not where you'd like to be on server side.

Alan Knight

unread,
Mar 25, 2013, 2:50:26 PM3/25/13
to John Messerly, General Dart Discussion
The simplest, or at least tersest, way is just
   myString.split("")
which gives you a list of all the one character strings. Although you should note that these will not strictly be letters, but UTF-16 code units, so you might get some half-characters in there. That may not matter to you, but if it does, then mapping the runes is probably the best thing.

I actually wrote an iterator that keeps the string and an index, and had it be bidirectional. That probably makes it a bit more efficient than mapping the runes and makes it a little easier to debug.

class _StringIterator implements BidirectionalIterator<String> {
  String s;
  var index = -1;
  inBounds(i) => i < 0 || i >= s.length;
  _StringIterator(this.s);
  String get current => inBounds(index) ? null : s[index];
  bool moveNext() => inBounds(++index);
  bool movePrevious() => inBounds(--index);
}

As far as efficiency in general, allocating all the substrings is definitely going to cost you. But I would be a bit leery about projecting performance based on current mechanisms. Things are changing very rapidly. And while 400K characters/second is not where you want to be if you're processing Google-sized log files, there are lots of applications (e.g. parsing number formatting patterns) where 400K/second would be quite adequate.

Alan Knight

unread,
Mar 26, 2013, 12:49:41 PM3/26/13
to John Messerly, General Dart Discussion
Note: Stupid logic errors in the previous code left as an exercise for the reader. I probably should think harder about work-in-progress code before posting it...
Reply all
Reply to author
Forward
0 new messages