슬라이스에서 요소 위치를 찾는 방법은 무엇입니까?


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 2011

8
왜 go coders가 이러한 공통 함수를 스스로 작성해야하는지 묻고있었습니다. 부동 값에 대한 다른 함수를 원하면이 함수를 복사 / 붙여 넣기해야합니다. 이것은 나를 위해 이상해 보였다. 그러나 Krzysztof Kowalczyk는 이미 golang에 제네릭이 없기 때문이라고 대답했습니다.
OCyril 2011

슬라이스가 정렬되어 있습니까?
고인돌

2
이 소스를 사용해보십시오 : gobyexample.com/collection-functions
Victor

답변:


70

죄송합니다.이를 수행 할 수있는 일반 라이브러리 함수가 없습니다. Go에는 모든 슬라이스에서 작동 할 수있는 함수를 작성하는 직접적인 방법이 없습니다.

함수는 작동하지만 range.

바이트 슬라이스가 있으면 bytes.IndexByte가 있습니다.


3
나는 Evan에게 동의합니다. 추가 코멘트 : 그것은 (bytes.IndexByte 등) "을 (를) 찾을 수 없습니다"나타냅니다 -1 단지 int로 반환하는 것이 더 관용적이다
르지 Kowalczyk

2
감사. 그러나 저는 약간 압도됩니다. :) golang을 사용하는 사람들로부터 프로그래머의 생산성을 높이기 위해 매우 잘 설계되었다고 여러 번 들었습니다. 그리고 go 프로그램은 파이썬 프로그램만큼 멋지게 보입니다. :) 그렇다면 왜 그런 일반적인 작업을 수행하는 일반적인 방법이 없습니까? 내 말은, 컨테이너에 요소가 있는지 확인하려면 그냥 할 수 있습니다if element in collection: do_something()
OCyril

10
기술적 답은 Go에 제네릭이 없기 때문입니다. 그랬다면 (그리고 미래의 어느 시점에 그것들을 가질 것입니다) ==를 구현하는 모든 유형에서 작동하는 일반 IndexInSlice를 작성할 수 있습니다. 내 바둑 옹호자 모자를 쓰는 것은 평균적인 경험에 관한 것입니다. 한 언어가 모든면에서 다른 모든 언어를 능가 할 것이라고 기대할 수는 없습니다. Go C, C ++, 아마도 Java 또는 C #보다 훨씬 생산적이며 Python에 가깝습니다. 프로그래머 생산성과 네이티브 코드 생성 (즉, 속도)의 조합이 매력적입니다.
Krzysztof Kowalczyk

1
또 다른 옵션은 일반 함수 생성을 위해 고차 함수와 클로저를 사용하는 것입니다. 예를 들어 답변을 추가했습니다.
Hodza

1
@OCyril 자신의 제네릭을 작성하고 자신의 라이브러리를 구축하거나 연구를 수행하고 필요에 맞는 것을 찾아야합니다. 가장 낮은 수준에서 '배열에서 값 찾기'함수 (PHP, Python 또는 기타)는 OP의 질문에 제공된 버전과 다소 비슷합니다. 루프는 숨겨져 있어도 이러한 종류의 프로그래밍의 중심입니다. Go는이 물건을 숨기지 않습니다.
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에 새로운 해요하지만 내가 읽은 기능)
팀 아벨

7
Buildtin 인덱스 함수는 항상 -1을 반환합니다. 이것은 예상되는 관용적 행동입니다. 누락 된 요소는 오류가 아닙니다.
Hodza 2015 년

환상적이다! 매우 유용합니다 :) 감사합니다!
Gaurav Ojha

12

함수를 작성할 수 있습니다.

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

요소와 일치하면 문자 / 문자열의 인덱스를 반환합니다. 찾을 수없는 경우 -1을 반환합니다.



2
func index(slice []string, item string) int {
    for i, _ := range slice {
        if slice[i] == item {
            return i
        }
    }
    return -1
}

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.