I want all possible three letter sets for a string. Scan does this:
irb>
“abcdefghijkl”.scan(…)
>> abc
>> def
>> ghi
>> jkl
But I need:
>> abc
>> bcd
>> cde
>> def
etc.
I used to know the secret spell, but forgot it. Does anyone know how
to do this with regular expression–basically need to force the index
to advance one position rather than to the end of a match before
starting the next attempt.
Thanks in advance,
Tim
I used to know the secret spell, but forgot it. Does anyone know how
to do this with regular expression
Here is one way to get that result.
(But not with a regular expression)
Not all 3 letter sets but I think this is the result you are really
looking for.
I fail to understand what do you mean by “all possible three-letter
sets”,
but it seems there is a method called ‘each_cons’ that does something in
the
lines of your discussion. You might find it helpful: http://corelib.rubyonrails.org/classes/Enumerable.html#M002196
I used to know the secret spell, but forgot it. Does anyone know how
to do this with regular expression–basically need to force the index
to advance one position rather than to the end of a match before
starting the next attempt.
Thanks in advance,
Tim
And another way.
Again without a regular expression.
str = “abcdefghijkl”
(0…str.length-3).each {|x| p str[x…x+2]}
I am not the OP, but thanks for that solution.
I learned more about regular expressions and relearned something about scan.
It did not work on my machine so I changed it to this.
p “abcdefghijkl”.scan(/(.)(?=(…))/).map{|x| x.join}
Is this map(&:join) using 1.9?
Yes. In general, &obj in that position triggers the use of obj.to_proc
as the code block for the method call, and in 1.9 there’s a built-in
Symbol#to_proc method.
On Mon, Jun 22, 2009 at 3:32 AM, David A. Black[email protected]
wrote:
Is this map(&:join) using 1.9?
Yes. In general, &obj in that position triggers the use of obj.to_proc
as the code block for the method call, and in 1.9 there’s a built-in
Symbol#to_proc method.
Sorry for highjacking the thread, but I believe it served its purpose
well, already ;).
Now it is clear that the above is not correct Ruby syntax. From my
experience very few people are fond of
the magic dot, which would solve the problem elegantly.
coll.map.join( ", " )
although in a very condensed way.
coll.map( ", ", &:join )
would be an alternative I kind of dislike.
Well burns down to
coll.map( :join, ", ")
And yes I know this is an old issue, but IIRC it has not been
discussed for some time
Cheers
Robert
–
Toutes les grandes personnes ont d’abord été des enfants, mais peu
d’entre elles s’en souviennent.
All adults have been children first, but not many remember.
I think it’s pretty ugly - especially the fact that you need the
argument ", " to be passed to join, not to map, and yet it appears in
map’s argument list.
Now it is clear that the above is not correct Ruby syntax. From my
experience very few people are fond of
the magic dot, which would solve the problem elegantly.
coll.map.join( ", " )
although in a very condensed way.
That I dislike very much. What you want is to run a ‘join’ operation on each member of the collection, but that looks like running a .map.join
on the whole collection. From that point of view,
require’enumerator’
“qwertyuiopasdfgd”.scan(/./).each_cons(3){|x,y,z| p [x,y,z].join}
I see that it will not output anything if the scan is omitted but why is
that so? It seems that it does not buy us anything of value.
Because String has a somehow strange way to implement Enumerables in
1.8 and in 1.9 there is simply no String#each_cons (because String is
not an enumerable anymore)
Personally I think it was a good decision, forcing people to be clear
how they want the String to be “iterated”
as there are some possibilities
“”.enum_for( x )
x in each_byte, each_char and ???
as a short for that you have
x.bytes → Enumerator
x.chars → Enumerator
But David has already applied this technique in one of the replies, so
I might not be DRY
HTH
Robert