Go에서 슬라이스를 반대로 반복하는 방법이 있습니까?


98

다음과 같이 말할 수 있으면 편리합니다.

for _, element := reverse range mySlice {
        ...
}

답변:


145

범위 1에 추가 할 편리한 연산자가 없습니다. 일반적인 for 루프 카운트 다운을 수행해야합니다.

s := []int{5, 4, 3, 2, 1}
for i := len(s)-1; i >= 0; i-- {
   fmt.Println(s[i])
}

효과적인 이동 페이지는 예는, 그러나 이것은 실제로 비트 좋네요 적은 변수를 선언합니다.
Kevin Cantwell

3
IMO Go는 하강 범위 구성이 절실히 필요합니다. 우리가 볼 수 있지 않는가 ...., 추가 작업의 좋은 거래를 원인 -
벡터

24
필사적으로 말하지 않을 것입니다.
Adam Kurkiewicz

47

다음을 수행 할 수도 있습니다.

s := []int{5, 4, 3, 2, 1}
for i := range s {
        fmt.Println(s[len(s)-1-i]) // Suggestion: do `last := len(s)-1` before the loop
}

산출:

1
2
3
4
5

또한 여기 : http://play.golang.org/p/l7Z69TV7Vl


15

색인이있는 변형

for k := range s {
        k = len(s) - 1 - k
        // now k starts from the end
    }

6

사용 연기 방법 :

s := []int{5, 4, 3, 2, 1}
for i, _ := range s {
   defer fmt.Println(s[i])
}

9
나는 그것이 새로운 지식을 가져 왔다는 사실에 대해 찬성 투표를 defer했지만, 이것을 역방향 루프 내에서 사용하는 것은 상당히 까다 롭고 메모리 측면에서 상당히 비효율적이어야한다고 생각합니다.
Alexander Trakhimenok

11
"작동"하지만 루프가 함수의 마지막 항목이 아니면 예기치 않은 결과를 얻을 수 있습니다. 예.
Daniel

6
이것은 defer의도하지 않은 방식으로 사용 하고 있습니다. 불쾌한 부작용이 발생할 수 있으므로 사용하지 마십시오 (실행 순서가 잘못됨). for허용되는 답변에서 루프를 사용하십시오 . Go는 이러한 종류의 영리한 (아님) 해킹 을 최소화하는 것을 목표로 하고 있습니다.
RickyA

6
이것은 defer의 엉뚱한 사용이므로 피해야합니다. 예를 들어 이것이 누군가가 미래에 확장 할 수있는 기능이라면 의도하지 않은 결과를 초래할 수 있습니다.
Amir Keibi

6
이것은 충분히 'iffy'가 아니었기 때문에 계속해서 play.golang.org/p/GodEiv1LlIJ
Xeoncross

4

하나는 채널을 사용하여 복제하지 않고 함수의 목록을 반전시킬 수 있습니다. 내 의미에서 코드를 더 멋지게 만듭니다.

package main

import (
    "fmt"
)

func reverse(lst []string) chan string {
    ret := make(chan string)
    go func() {
        for i, _ := range lst {
            ret <- lst[len(lst)-1-i]
        }
        close(ret)
    }()
    return ret
}

func main() {
    elms := []string{"a", "b", "c", "d"}
    for e := range reverse(elms) {
        fmt.Println(e)
    }
}

그것은 나에게 깨끗하고 사용하기 좋은 솔루션처럼 보입니다. 유형을 사용하여 이것을 일반화 할 수 []interface{}있습니까? 현재 reverse기능은 문자열 만 지원하기 때문입니다.
Atmocreations

확실하게 string을 interface {}로 바꾸면됩니다. 서명 func reverse(lst []interface{}) chan inyterface{} 이 있는 함수는 더 이상 [] 문자열을 입력으로 사용하지 않는다는 점을 강조하고 싶습니다 . string은 interface {}에서 캐스트 할 수 있지만 [] string은 [] interface {}에서 캐스트 할 수 없습니다. 불행히도 현재의 역함수는 많이 다시 작성해야하는 기능입니다.
user983716

감사합니다. 그게 제가 생각하기에 바둑의 추악한 부분입니다. 감사합니다!
Atmocreations 2015 년

이것보다는 스택을 구현할 것입니다.
ᐅ devrimbaris 2018

0

슬라이스 및 역방향 범위에서 요소를 추출해야 할 때 다음 코드와 같은 것을 사용합니다.

// reverse range
// Go Playground: https://play.golang.org/p/gx6fJIfb7fo
package main

import (
    "fmt"
)

type Elem struct {
    Id   int64
    Name string
}

type Elems []Elem

func main() {
    mySlice := Elems{{Id: 0, Name: "Alice"}, {Id: 1, Name: "Bob"}, {Id: 2, Name: "Carol"}}
    for i, element := range mySlice {
        fmt.Printf("Normal  range: [%v] %+v\n", i, element)
    }

    //mySlice = Elems{}
    //mySlice = Elems{{Id: 0, Name: "Alice"}}
    if last := len(mySlice) - 1; last >= 0 {
        for i, element := last, mySlice[0]; i >= 0; i-- {
            element = mySlice[i]
            fmt.Printf("Reverse range: [%v] %+v\n", i, element)
        }
    } else {
        fmt.Println("mySlice empty")
    }
}

산출:

Normal  range: [0] {Id:0 Name:Alice}
Normal  range: [1] {Id:1 Name:Bob}
Normal  range: [2] {Id:2 Name:Carol}
Reverse range: [2] {Id:2 Name:Carol}
Reverse range: [1] {Id:1 Name:Bob}
Reverse range: [0] {Id:0 Name:Alice}

플레이 그라운드 : https://play.golang.org/p/gx6fJIfb7fo

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.