Bagaimana cara membandingkan string di GoLang?

93

Saya tidak dapat memberikan hasil yang 'benar' dalam hal perbandingan string Go. Saya menulis yang berikut ini untuk menjelaskan masalah dan melampirkan tangkapan layar dari hasilnya

// string comparison in Go
package main
import "fmt"
import "bufio"
import "os"

func main() {
    var isLetterA bool 

    fmt.Println("Enter the letter a")
    reader := bufio.NewReader(os.Stdin)
    input, _ := reader.ReadString('\n')

    if(input == "a") {
        isLetterA = true
    } else {
        isLetterA = false 
    }

    fmt.Println("You entered",input)
    fmt.Println("Is it the letter a?",isLetterA)

}

contoh

pengguna2202911
sumber
pengguna windows memeriksa jawaban saya :)
Daksh Miglani

Jawaban:

132

==adalah operator yang tepat untuk membandingkan string di Go. Namun, string yang Anda baca dari STDIN reader.ReadStringtidak berisi "a", tetapi "a\n"(jika Anda melihat lebih dekat, Anda akan melihat jeda baris tambahan dalam contoh output Anda).

Anda dapat menggunakan strings.TrimRightfungsi ini untuk menghapus spasi kosong dari input Anda:

if strings.TrimRight(input, "\n") == "a" {
    // ...
}
helmbert
sumber
9

Untuk Pengguna Independen Platform atau pengguna Windows, yang dapat Anda lakukan adalah:

impor runtime:

import (
    "runtime"
    "strings"
)

lalu potong senar seperti ini:

if runtime.GOOS == "windows" {
  input = strings.TrimRight(input, "\r\n")
} else {
  input = strings.TrimRight(input, "\n")
}

sekarang Anda bisa membandingkannya seperti itu:

if strings.Compare(input, "a") == 0 {
  //....yourCode
}

Ini adalah pendekatan yang lebih baik saat Anda menggunakan STDIN di berbagai platform.

Penjelasan

Hal ini terjadi karena pada baris windows diakhiri dengan "\r\n"yang dikenal sebagai CRLF, tetapi pada baris UNIX diakhiri dengan "\n"yang dikenal sebagai LF dan itulah mengapa kami memangkas "\n"pada sistem operasi berbasis unix sementara kami memotong "\r\n"pada windows.

Daksh Miglani
sumber
4
Tidak perlu membedakan. Argumen kedua adalah cutset, bukan sufiks, dan karakter apa pun dalam cutset akan dipangkas, dalam urutan / kombinasi apa pun. Memangkas "\ r \ n" sudah cukup untuk keduanya.
Jason Carlson
1

Dengan asumsi tidak ada karakter spasi kosong sebelum / sesudah, masih ada beberapa cara untuk menegaskan persamaan string. Beberapa di antaranya adalah:

Berikut beberapa hasil benchmark dasar (dalam pengujian ini, strings.EqualFold(.., ..)sepertinya pilihan yang paling berkinerja):

goos: darwin
goarch: amd64
BenchmarkStringOps/both_strings_equal::equality_op-4               10000        182944 ns/op
BenchmarkStringOps/both_strings_equal::strings_equal_fold-4        10000        114371 ns/op
BenchmarkStringOps/both_strings_equal::fold_caser-4                10000       2599013 ns/op
BenchmarkStringOps/both_strings_equal::lower_caser-4               10000       3592486 ns/op

BenchmarkStringOps/one_string_in_caps::equality_op-4               10000        417780 ns/op
BenchmarkStringOps/one_string_in_caps::strings_equal_fold-4        10000        153509 ns/op
BenchmarkStringOps/one_string_in_caps::fold_caser-4                10000       3039782 ns/op
BenchmarkStringOps/one_string_in_caps::lower_caser-4               10000       3861189 ns/op

BenchmarkStringOps/weird_casing_situation::equality_op-4           10000        619104 ns/op
BenchmarkStringOps/weird_casing_situation::strings_equal_fold-4    10000        148489 ns/op
BenchmarkStringOps/weird_casing_situation::fold_caser-4            10000       3603943 ns/op
BenchmarkStringOps/weird_casing_situation::lower_caser-4           10000       3637832 ns/op

Karena ada beberapa opsi, jadi inilah kode untuk menghasilkan tolok ukur.

package main

import (
    "fmt"
    "strings"
    "testing"

    "golang.org/x/text/cases"
    "golang.org/x/text/language"
)

func BenchmarkStringOps(b *testing.B) {
    foldCaser := cases.Fold()
    lowerCaser := cases.Lower(language.English)

    tests := []struct{
        description string
        first, second string
    }{
        {
            description: "both strings equal",
            first: "aaaa",
            second: "aaaa",
        },
        {
            description: "one string in caps",
            first: "aaaa",
            second: "AAAA",
        },
        {
            description: "weird casing situation",
            first: "aAaA",
            second: "AaAa",
        },
    }

    for _, tt := range tests {
        b.Run(fmt.Sprintf("%s::equality op", tt.description), func(b *testing.B) {
            for i := 0; i < b.N; i++ {
                benchmarkStringEqualsOperation(tt.first, tt.second, b)
            }
        })

        b.Run(fmt.Sprintf("%s::strings equal fold", tt.description), func(b *testing.B) {
            for i := 0; i < b.N; i++ {
                benchmarkStringsEqualFold(tt.first, tt.second, b)
            }
        })

        b.Run(fmt.Sprintf("%s::fold caser", tt.description), func(b *testing.B) {
            for i := 0; i < b.N; i++ {
                benchmarkStringsFoldCaser(tt.first, tt.second, foldCaser, b)
            }
        })

        b.Run(fmt.Sprintf("%s::lower caser", tt.description), func(b *testing.B) {
            for i := 0; i < b.N; i++ {
                benchmarkStringsLowerCaser(tt.first, tt.second, lowerCaser, b)
            }
        })
    }
}

func benchmarkStringEqualsOperation(first, second string, b *testing.B) {
    for n := 0; n < b.N; n++ {
        _ = strings.ToLower(first) == strings.ToLower(second)
    }
}

func benchmarkStringsEqualFold(first, second string, b *testing.B) {
    for n := 0; n < b.N; n++ {
        _ = strings.EqualFold(first, second)
    }
}

func benchmarkStringsFoldCaser(first, second string, caser cases.Caser, b *testing.B) {
    for n := 0; n < b.N; n++ {
        _ = caser.String(first) == caser.String(second)
    }
}

func benchmarkStringsLowerCaser(first, second string, caser cases.Caser, b *testing.B) {
    for n := 0; n < b.N; n++ {
        _ = caser.String(first) == caser.String(second)
    }
}
Debosmit Ray
sumber
0

Konten di dalam string di Golang dapat dibandingkan menggunakan ==operator. Jika hasilnya tidak seperti yang diharapkan mungkin ada beberapa karakter tersembunyi seperti \n,, \rspasi, dll. Jadi sebagai pedoman umum, coba hapus yang menggunakan fungsi yang disediakan oleh stringspaket di golang.

Untuk Instance, spasi dapat dihapus menggunakan strings.TrimSpacefungsi. Anda juga dapat menentukan fungsi khusus untuk menghapus karakter apa pun yang Anda butuhkan. strings.TrimFuncfungsi dapat memberi Anda lebih banyak kekuatan.

Abhishek Srivastava
sumber