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.