Is there an easy reverse range operator?

7,703 views
Skip to first unread message

Robert Snedegar

unread,
Oct 24, 2012, 4:02:40 PM10/24/12
to golang-nuts
Is there a simple way to reverse range over any rangeable item?

for k, v := reverse range fooBar {
// blah
}

For arrays/slices I know I can just as easily do a for loop counting
down, but for other types that can be ranged over, it's not as obvious
what is the easy equivalent is. Do I need to rewrite my own copy of
Len/Less/Swap for every type I want to use and sort of build my own
Reverse sort.Interface? (i.e.
http://golang.org/pkg/sort/#example_Interface_reverse )

- Robert

Rémy Oudompheng

unread,
Oct 24, 2012, 4:04:29 PM10/24/12
to Robert Snedegar, golang-nuts
On 2012/10/24 Robert Snedegar <vik...@gmail.com> wrote:
> Is there a simple way to reverse range over any rangeable item?
>
> for k, v := reverse range fooBar {
> // blah
> }
>
> For arrays/slices I know I can just as easily do a for loop counting
> down, but for other types that can be ranged over, it's not as obvious
> what is the easy equivalent is.

What are these "other types" you are thinking of?

Rémy.

Matt Kane's Brain

unread,
Oct 24, 2012, 4:09:49 PM10/24/12
to Rémy Oudompheng, Robert Snedegar, golang-nuts
Strings you can do just fine as long as you convert them to []rune
instead of []byte
Maps have no defined order.
Channels in reverse order? Violates causality.

On Wed, Oct 24, 2012 at 4:04 PM, Rémy Oudompheng
<remyoud...@gmail.com> wrote:
>> For arrays/slices I know I can just as easily do a for loop counting
>> down, but for other types that can be ranged over, it's not as obvious
>> what is the easy equivalent is.


--
matt kane's brain
http://hydrogenproject.com

Sanjay

unread,
Oct 24, 2012, 4:14:10 PM10/24/12
to golan...@googlegroups.com, Rémy Oudompheng, Robert Snedegar
You don't need to convert to []rune. You can use http://tip.golang.org/pkg/unicode/utf8/#DecodeLastRuneInString and slicing to do this. See the example for that function.

Sanjay

小菜

unread,
Sep 3, 2014, 10:00:06 PM9/3/14
to golan...@googlegroups.com
I want to know too!


。。。 

egon

unread,
Sep 4, 2014, 3:05:40 AM9/4/14
to golan...@googlegroups.com


On Wednesday, 24 October 2012 23:02:48 UTC+3, Robert wrote:
Is there a simple way to reverse range over any rangeable item?

for k, v := reverse range fooBar {
        // blah
}


It makes only sense for arrays/slices...

for i := len(foobar) -1; i >= 0; i-- {
   v := foobar[i]
   // blah
}

... or

for i := range foobar {
   v := foobar[len(foobar) - i - 1]
   // blah
}

It does not make sense to provide such operator.

Dave Cheney

unread,
Sep 4, 2014, 5:02:10 AM9/4/14
to golan...@googlegroups.com
Nope. Write a loop.

rjeczalik

unread,
Sep 4, 2014, 5:28:28 AM9/4/14
to egon, golang-nuts
On 4 September 2014 09:05, egon <egon...@gmail.com> wrote:
It does not make sense to provide such operator.

Theoretically it may, especially when 'for _, v := range ...' does not perform bound checks, and hand-crafted loops do.

egon

unread,
Sep 4, 2014, 5:31:47 AM9/4/14
to golan...@googlegroups.com, egon...@gmail.com
I'm guessing you'll get a bigger performance hit from traversing memory backwards than from bounds checks. But it's just a guess, I don't have data to back that up.

+ egon

Jan Mercl

unread,
Sep 4, 2014, 5:37:02 AM9/4/14
to rjeczalik, egon, golang-nuts
On Thu, Sep 4, 2014 at 11:27 AM, rjeczalik <rjec...@gmail.com> wrote:
> Theoretically it may, especially when 'for _, v := range ...' does not
> perform bound checks, and hand-crafted loops do.

The language specification has no guarantees about bounds check in a
for statement. The implementation is free to remove them when
possible. Hand-crafted loops may not apply always, but often they can.

-j

Dave Cheney

unread,
Sep 4, 2014, 5:37:13 AM9/4/14
to egon, golan...@googlegroups.com
Unless all you are doing is walking backwards through the slice, any work you do on a element in the slice will probably eclipse any bounds checking cost -- which the processor has probably eliminated via branch prediction. 


--
You received this message because you are subscribed to a topic in the Google Groups "golang-nuts" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/golang-nuts/8POFxbr_bAg/unsubscribe.
To unsubscribe from this group and all its topics, send an email to golang-nuts...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Lewis Dackam

unread,
Sep 4, 2014, 9:02:00 PM9/4/14
to golan...@googlegroups.com
You could do it elegantly with the defer keyword.

package main

import "fmt"

func main() {
fmt.Println("Reverse a string with a for range")
str2 := "string2"
for index, _ := range str2 {
defer fmt.Printf("%c", str2[index])
}
}

Rob Pike

unread,
Sep 4, 2014, 9:17:30 PM9/4/14
to Lewis Dackam, golan...@googlegroups.com
I snorted.

-rob
> --
> You received this message because you are subscribed to the Google Groups
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an

Ian Lance Taylor

unread,
Sep 4, 2014, 10:46:28 PM9/4/14
to Lewis Dackam, golang-nuts
On Thu, Sep 4, 2014 at 6:01 PM, Lewis Dackam <lewis....@gmail.com> wrote:
>
> You could do it elegantly with the defer keyword.

Nice technique, and easy to use a named result to gather the
characters.

http://play.golang.org/p/0IYOHrfkUh

Ian

Rob Pike

unread,
Sep 5, 2014, 4:04:34 PM9/5/14
to Ian Lance Taylor, Lewis Dackam, golang-nuts
There's always the LISP way, updated for Unicode.

http://play.golang.org/p/Yx8ZU87N6m

The same method without recursion.

http://play.golang.org/p/ntBtXHmwWK

But you wanted a range loop.

http://play.golang.org/p/8yy7CQn5l3

And now we have diverged so far from the original question that we can
safely ignore it.

-rob

adon...@google.com

unread,
Sep 5, 2014, 4:14:07 PM9/5/14
to golan...@googlegroups.com, lewis....@gmail.com
The efficiency of this program troubles me...  that 'return' statement is too efficient.
Fortunately we can do without it: http://play.golang.org/p/I-I2WzrXPG

Rob Pike

unread,
Sep 5, 2014, 4:21:24 PM9/5/14
to Alan Donovan, golan...@googlegroups.com, Lewis D
Not Unicode-safe. Bad.

-rob
Reply all
Reply to author
Forward
0 new messages