क्या गो में रिवर्स में एक स्लाइस पर पुनरावृति करने का एक तरीका है?


98

यह कुछ कहने में सक्षम होने के लिए सुविधाजनक होगा:

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

जवाबों:


145

नहीं, इसके लिए कोई सुविधाजनक ऑपरेटर नहीं है जो रेंज में एक को जोड़ सके। आपको लूप काउंटिंग के लिए एक सामान्य करना होगा:

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

प्रभावी जाने पेज एक उदाहरण है, लेकिन यह एक वास्तव में एक सा अच्छे है और कम चर की घोषणा की।
केविन कैंवेल

3
IMO Go को एक अवरोही श्रेणी निर्माण की सख्त आवश्यकता है। यह नहीं होने से अतिरिक्त काम का एक अच्छा सौदा होता है, जैसा कि हम देख सकते हैं .... -
वेक्टर

24
मैं सख्त नहीं कहूंगा, यह एक अच्छा होगा।
एडम कुर्कविक्ज़

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



6

कैसे उपयोग defer के बारे में:

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

9
मैंने सिर्फ इस तथ्य के लिए मतदान किया है कि यह कुछ नया ज्ञान लेकर आया है, deferलेकिन मेरा मानना ​​है कि रिवर्स के लिए लूप के अंदर इसका उपयोग करना काफी मुश्किल है और यह बहुत ही अप्रभावी मेमोरी-वार होना चाहिए।
अलेक्जेंडर ट्रेखिमेनोक

11
यह "काम करता है", लेकिन अगर लूप फ़ंक्शन में अंतिम चीज नहीं है तो आपको अप्रत्याशित परिणाम मिल सकते हैं। उदाहरण।
डेनियल

6
यह इस तरह से उपयोग कर deferरहा है जैसा कि इसके लिए इरादा नहीं है। इसका उपयोग न करें क्योंकि इससे बुरा दुष्प्रभाव (ऑर्डर निष्पादन से बाहर) हो सकता है। बस forस्वीकृत उत्तर में लूप का उपयोग करें । गो को इस तरह की चालाक (नहीं) हैक्स को कम करने का लक्ष्य है क्योंकि वे बाद में आपको गधे में काटते हैं।
रिका

6
यह डिफरेंस का हैक करने वाला प्रयोग है और इससे बचना चाहिए। यदि यह है, उदाहरण के लिए, एक फ़ंक्शन जिसे कोई भविष्य में विस्तारित कर सकता है, तो इसके अनपेक्षित परिणाम हो सकते हैं।
अमीर केबी

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

निश्चित रूप से, बस स्ट्रिंग को इंटरफ़ेस {} से बदलें और आप गो के लिए अच्छे हैं। मैं सिर्फ इस बात पर जोर देना चाहता हूं कि हस्ताक्षर के साथ एक फ़ंक्शन func reverse(lst []interface{}) chan inyterface{} इनपुट के रूप में एक [] स्ट्रिंग नहीं लेगा। यदि स्ट्रिंग को इंटरफ़ेस {} में डाला जा सकता है, तो भी [] इंटरफ़ेस {} में स्ट्रिंग डाली नहीं जा सकती। दुर्भाग्य से, वर्तमान रिवर्स फ़ंक्शन एक प्रकार का फ़ंक्शन है जिसे बहुत कुछ फिर से लिखना पड़ता है।
user983716

धन्यवाद। मुझे लगता है कि जाने का यह बदसूरत हिस्सा है - जो किसी भी तरह अपरिहार्य है। धन्यवाद!
एटमोक्रीटेशन

मैं इसके बजाय एक स्टैक लागू करूंगा।
at देवब्रिम्बरिस

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

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.