จะหาตำแหน่งองค์ประกอบในชิ้นได้อย่างไร?


108

เราจะกำหนดตำแหน่งขององค์ประกอบที่อยู่ในชิ้นได้อย่างไร?

ฉันต้องการสิ่งต่อไปนี้:

type intSlice []int

func (slice intSlice) pos(value int) int {
    for p, v := range slice {
        if (v == value) {
            return p
        }
    }
    return -1
}

2
คำถามคืออะไร? รหัสไม่ทำงาน?
newacct

9
ฉันถามว่าทำไมนักเขียนโค้ดจึงควรเขียนฟังก์ชันทั่วไปด้วยตัวเอง ฉันหมายความว่าถ้าฉันต้องการฟังก์ชันอื่นสำหรับค่าลอยฉันจะถูกบังคับให้คัดลอก / วางฟังก์ชันนี้ สิ่งนี้ดูแปลกสำหรับฉัน แต่ Krzysztof Kowalczyk ได้ตอบไปแล้วว่าเป็นเพราะโกลังไม่มียาชื่อสามัญ
OCyril

ชิ้นของคุณถูกจัดเรียงหรือไม่?
dolmen

2
ลองใช้แหล่งข้อมูลนี้: gobyexample.com/collection-functions
วิกเตอร์

คำตอบ:


70

ขออภัยไม่มีฟังก์ชันไลบรารีทั่วไปที่จะทำสิ่งนี้ Go ไม่มีวิธีเขียนฟังก์ชันแบบตรงไปตรงมาที่สามารถทำงานบนสไลซ์ใด ๆ

ฟังก์ชันของคุณใช้งานได้แม้ว่าจะดีกว่าเล็กน้อยหากคุณเขียนโดยใช้range.

หากคุณเกิดขึ้นจะมีชิ้นไบต์มีbytes.IndexByte


3
ฉันเห็นด้วยกับ Evan ความคิดเห็นเพิ่มเติม: มันเป็นสำนวนมากกว่าที่จะคืนค่า int โดยที่ -1 ระบุว่า "not found" (เช่น bytes.IndexByte)
Krzysztof Kowalczyk

3
ขอบคุณ. แต่ฉันรู้สึกแย่เล็กน้อย :) ฉันได้ยินหลายครั้งจากคนที่ใช้ golang ว่ามันถูกออกแบบมาเป็นอย่างดีเพื่อเพิ่มประสิทธิภาพการทำงานของโปรแกรมเมอร์ และโปรแกรม go ก็ดูดีเหมือน python :) เหตุใดจึงไม่มีวิธีทั่วไปในการทำงานทั่วไปเช่นนี้? ฉันหมายความว่าถ้าคุณต้องการตรวจสอบว่าคอนเทนเนอร์มีองค์ประกอบหรือไม่คุณก็ทำได้if element in collection: do_something()
OCyril

10
คำตอบทางเทคนิคคือเนื่องจาก Go ไม่มีชื่อสามัญ หากเป็นเช่นนั้น (และในอนาคตอาจมี) คุณสามารถเขียน IndexInSlice ทั่วไปที่ใช้งานได้กับทุกประเภทที่ใช้ == การใส่หมวกผู้สนับสนุน Go ของฉัน: เป็นเรื่องของประสบการณ์โดยเฉลี่ย คุณไม่สามารถคาดหวังว่าภาษาเดียวจะเอาชนะภาษาอื่น ๆ ในทุกๆด้านได้ Go มีประสิทธิผลมากกว่า C, C ++ อาจจะเป็น Java หรือ C # และใกล้เคียงกับ python เป็นการผสมผสานระหว่างผลผลิตของโปรแกรมเมอร์และการสร้างโค้ดเนทีฟ (เช่นความเร็ว) ที่ทำให้น่าสนใจ
Krzysztof Kowalczyk

1
อีกทางเลือกหนึ่งคือการใช้ฟังก์ชันลำดับที่สูงขึ้นและการปิดเพื่อสร้างฟังก์ชันทั่วไป ฉันเพิ่มคำตอบพร้อมตัวอย่าง
ฮอดซ่า

1
@OCyril คุณต้องเขียนชื่อสามัญของคุณเองและสร้างห้องสมุดของคุณเองหรือทำการค้นคว้าและค้นหาสิ่งที่เหมาะกับความต้องการของคุณ ที่ระดับต่ำสุดฟังก์ชัน 'find value = x in array' (PHP, Python หรืออะไรก็ได้) จะดูเหมือนเวอร์ชันที่ระบุในคำถามของ OP ซึ่งอยู่ในระดับต่ำ ลูปเป็นศูนย์กลางของการเขียนโปรแกรมประเภทนี้แม้ว่าจะซ่อนอยู่ก็ตาม โกไม่ซ่อนสิ่งนี้
Ian Lewis

54

คุณสามารถสร้างฟังก์ชั่นทั่วไปในสำนวนไป:

func SliceIndex(limit int, predicate func(i int) bool) int {
    for i := 0; i < limit; i++ {
        if predicate(i) {
            return i
        }
    }
    return -1
}

และการใช้งาน:

xs := []int{2, 4, 6, 8}
ys := []string{"C", "B", "K", "A"}
fmt.Println(
    SliceIndex(len(xs), func(i int) bool { return xs[i] == 5 }),
    SliceIndex(len(xs), func(i int) bool { return xs[i] == 6 }),
    SliceIndex(len(ys), func(i int) bool { return ys[i] == "Z" }),
    SliceIndex(len(ys), func(i int) bool { return ys[i] == "A" }))

1
รักสิ่งนี้ แต่ฉันคิดว่ามันยากที่จะคิดแบบนี้
Decebal

1
ฉันไม่คิดว่าการส่งคืน-1ข้อผิดพลาดเป็นสำนวน แต่ควรใช้การส่งคืนหลายครั้งแทน (ฉันยังใหม่กับ golang แต่นั่นคือสิ่งที่ฉันได้อ่าน)
Tim Abell

7
Buildtin index funcs in go กลับเสมอ -1 นี่เป็นพฤติกรรมสำนวนที่คาดหวัง องค์ประกอบที่ขาดหายไปไม่ใช่ข้อผิดพลาด
Hodza

นี่มันสุดยอดมาก! มีประโยชน์มาก :) ขอบคุณ!
Gaurav Ojha

13

คุณสามารถเขียนฟังก์ชัน

func indexOf(element string, data []string) (int) {
   for k, v := range data {
       if element == v {
           return k
       }
   }
   return -1    //not found.
}

สิ่งนี้จะส่งคืนดัชนีของอักขระ / สตริงหากตรงกับองค์ประกอบ หากไม่พบให้ส่งกลับค่า -1


6

ไม่มีฟังก์ชันไลบรารีสำหรับสิ่งนั้น คุณต้องเขียนโค้ดด้วยตัวคุณเอง



1

อีกทางเลือกหนึ่งคือการจัดเรียงชิ้นส่วนโดยใช้แพ็กเกจการจัดเรียงจากนั้นค้นหาสิ่งที่คุณกำลังมองหา:

package main

import (
    "sort"
    "log"
    )

var ints = [...]int{74, 59, 238, -784, 9845, 959, 905, 0, 0, 42, 7586, -5467984, 7586}

func main() {
        data := ints
        a := sort.IntSlice(data[0:])
        sort.Sort(a)
        pos := sort.SearchInts(a, -784)
        log.Println("Sorted: ", a)
        log.Println("Found at index ", pos)
}

พิมพ์

2009/11/10 23:00:00 Sorted:  [-5467984 -784 0 0 42 59 74 238 905 959 7586 7586 9845]
2009/11/10 23:00:00 Found at index  1

สิ่งนี้ใช้ได้กับประเภทพื้นฐานและคุณสามารถใช้อินเทอร์เฟซการจัดเรียงสำหรับประเภทของคุณเองได้ตลอดเวลาหากคุณต้องการทำงานในส่วนอื่น ๆ ดูhttp://golang.org/pkg/sort

ขึ้นอยู่กับว่าคุณกำลังทำอะไรอยู่


โอเคขอบคุณ. แต่ฉันเดาว่ามันดูแปลกที่จะใช้สิ่งนี้หากฉันต้องการตรวจสอบว่าชิ้นส่วนมีองค์ประกอบที่กำหนดหรือไม่ :)
OCyril

3
สิ่งนี้ไม่พบดัชนีดั้งเดิม ค่อนข้างจะสูญเสียดัชนีทั้งหมดด้วยการสั่งซื้อใหม่
newacct

แน่นอนว่าสาเหตุนั้นขึ้นอยู่กับการใช้งาน ถ้ามันเป็นเพียงแค่การตรวจสอบแล้วตรวจสอบว่าเพียงแค่ใช้และfor p, v := range ... ifแค่อยากจะชี้ให้เห็นตัวเลือก
robothor
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.