পাই কি পাইথনের অনুরূপ "যদি এক্স ইন" নির্মিত হয়?


289

ছাড়া সমগ্র অ্যারের উপর iterating, কিভাবে আমি পরীক্ষা করতে পারবেন xঅ্যারের মধ্যে যান ব্যবহার করছেন? ভাষার কি কোন নির্মাণ রয়েছে?

পাইথনের মতো: if "x" in array: ...


2
একটি প্রতারিত হতে পারে stackoverflow.com/q/8307478/180100

7
আফাইক, সেখানে যাওয়ার জন্য শর্টহ্যান্ড নেই। অভ্যন্তরীণভাবে, অজগরটি অ্যারের উপরেও পুনরাবৃত্তি করে, এটির কাছাকাছি কোনও জিনিস নেই।
ডেনিশ

6
বিটিডাব্লু, এটির জন্য একটি গুরুত্বপূর্ণ দ্রষ্টব্য হ'ল এটি করার কোনও উপায় নেই (যেমন আপনি জিজ্ঞাসা করছেন) " [ডাব্লু] পুরো অ্যারির উপর দিয়ে পুনরুক্তি "। এ জাতীয় লুপগুলি সুস্পষ্টভাবে তৈরি করা (বা কোনও ফাংশনের পিছনে strings.Index) কোড কী করছে তা আরও সুস্পষ্ট করতে সহায়তা করে। আমি ধারণাটি পেয়েছি যে সম্ভবত আপনি মনে করেন পাইথনগুলি in array:দ্রুত / যাদুতে কিছু করছে। আফাইক এটি না। লুপটি স্পষ্ট করে লেখককে (এবং সমস্ত পাঠক) সচেতন করতে এবং অন্যান্য বাস্তবায়নগুলি (যেমন একটি মানচিত্র) বিবেচনা করতে সহায়তা করে।
ডেভ সি

5
যাইহোক, যদি সেট "এক্স" সত্যই খুব দ্রুত হয়।
রবার্তো আলসিনা

6
আমি মনে করি না আমরা একটি অগ্রগতিশীল দ্রুত পদ্ধতির জন্য জিজ্ঞাসা করছি, আমরা কেবল একটি সংক্ষিপ্তটির জন্য জিজ্ঞাসা করছি (এবং এখনও পাইনি ...)
মাইগওয়েল

উত্তর:


339

এটি করতে কোনও বিল্ট-ইন অপারেটর নেই। আপনাকে অ্যারে দিয়ে পুনরাবৃত্তি করতে হবে। এটি করার জন্য আপনি নিজের ফাংশনটি লিখতে পারেন:

func stringInSlice(a string, list []string) bool {
    for _, b := range list {
        if b == a {
            return true
        }
    }
    return false
}

আপনি যদি পুরো তালিকার পুনরাবৃত্তি না করে সদস্যতার জন্য যাচাই করতে সক্ষম হতে চান তবে আপনাকে এই জাতীয় বিন্যাস বা স্লাইসের পরিবর্তে একটি মানচিত্র ব্যবহার করতে হবে:

visitedURL := map[string]bool {
    "http://www.google.com": true,
    "https://paypal.com": true,
}
if visitedURL[thisSite] {
    fmt.Println("Already been here.")
}

4
প্রকার উল্লেখ না করে এটি করার কোনও উপায় আছে? আসুন আমি যদি বলি যে আমি প্রতিটি সাধারণ ধরণের জন্য পৃথক পদ্ধতি ছাড়াই কেবলমাত্র একটি সাধারণ সুই ইনহাইস্ট্যাক (সূঁচ, খড়ের ছিদ্র) ফাংশন চাই
অ্যালেন

25
এটি প্রতিবিম্ব প্যাকেজটির সাহায্যে করা যেতে পারে তবে এটি মোটামুটি অদক্ষ হয়ে উঠবে (সম্ভবত এতটা ধীরগতির মতো আপনি এটি পাইথনের মতো গতিশীল ভাষায় লিখেছিলেন)। তা ছাড়া আর না। লোকেরা যখন বোঝায় যে গো জেনেরিকস নেই তখন এটাই বোঝায়।
andybalholm

2
এই উত্তরের যে কেউ হোঁচট খেয়েছে তাকে অবশ্যই নোট করে রাখতে পারবেন না maps গো মানচিত্র ব্যবহার করতে বড় ক্ষতি।
রাইজিংসুন

4
আপনি জাভাস্ক্রিপ্টে মানচিত্র (অবজেক্টস) বাছাই করতে পারবেন না। এটি একটি ভি 8 বাগ যা অক্ষর অনুসারে বাছাইকৃত ক্রমে মানগুলি ফেরত দেয়।
কুমারহর্স

7
মানচিত্রগুলি বেশিরভাগ ভাষায় সাজানো হয় না - এটি মানচিত্রের ডেটা স্ট্রাকচারের (হ্যাশম্যাপ) কোর্সের সমান।
হিজাজমান

100

আর একটি সমাধান যদি তালিকায় স্থির মান থাকে।

যেমন: বৈধ মানগুলির তালিকা থেকে একটি বৈধ মানের জন্য পরীক্ষা করা:

func IsValidCategory(category string) bool {
    switch category {
    case
        "auto",
        "news",
        "sport",
        "music":
        return true
    }
    return false
}

11
হ্যাঁ, যদি আপনার "বৈধ মানগুলি" ডাটাবেস থেকে আসে?
রামি দাবাইন

হ্যাঁ, এটি পরিষ্কার তবে কেবল যখন এই মানগুলি আগে থেকেই সংজ্ঞায়িত করা যায়।
পিগিগবক্স

2
@ রোনানডেজেরো তখন আমি কোথায় ব্যবহার করতে পারলাম: মাইভ্যালু ইন (সাবকিউরি) :)
এনিলেক

3
এটি শীর্ষ জবাবের সাথে ঝরঝরে তুলনা করছে
piggybox

50

এটি "প্রোগ্রামিং ইন গো: একবিংশ শতাব্দীর জন্য অ্যাপ্লিকেশন তৈরি করা" বইয়ের উদ্ধৃতি:

এর মতো সরল রৈখিক অনুসন্ধান ব্যবহার করা অচলিত ডেটার একমাত্র বিকল্প এবং ছোট টুকরো (শত শত আইটেম পর্যন্ত) জন্য এটি জরিমানা। তবে বৃহত্তর টুকরোগুলির জন্য - বিশেষত যদি আমরা বার বার অনুসন্ধানগুলি চালাচ্ছি - লিনিয়ার সন্ধানটি খুব অকার্যকর, গড়ে প্রতিবারের তুলনায় অর্ধেক আইটেমের প্রয়োজন হয়।

গো একটি বাছাই দেয় earch অনুসন্ধান () পদ্ধতি যা বাইনারি অনুসন্ধান অ্যালগরিদম ব্যবহার করে: এটি প্রতিবার কেবল লগ 2 (এন) আইটেমের (যেখানে এন আইটেমের সংখ্যা হয়) তুলনা প্রয়োজন। এটিকে দৃষ্টিকোণে বলতে গেলে, 1000000 আইটেমগুলির একটি রৈখিক অনুসন্ধানের জন্য 1000000 তুলনার সবচেয়ে খারাপ ক্ষেত্রে, গড়ে গড়ে 500000 তুলনা প্রয়োজন; একটি বাইনারি অনুসন্ধানের জন্য প্রায় 20 টি তুলনা প্রয়োজন, এমনকি সবচেয়ে খারাপ ক্ষেত্রেও।

files := []string{"Test.conf", "util.go", "Makefile", "misc.go", "main.go"}
target := "Makefile"
sort.Strings(files)
i := sort.Search(len(files),
    func(i int) bool { return files[i] >= target })
if i < len(files) && files[i] == target {
    fmt.Printf("found \"%s\" at files[%d]\n", files[i], i)
}

https://play.golang.org/p/UIndYQ8FeW


10
আপনি যদি বার বার অনুসন্ধান করেন তবে এটি বোধগম্য হয়। অন্যথায় আপনি জটিলতা পেয়েছেন এন * লগ (এন) * লগ (এন) সাজানোর জন্য এবং বাইনারি অনুসন্ধানের জন্য, লিনিয়ার সন্ধানের জন্য কেবল এন us
খ্রিস্টান

1
এটি আসলে ঠিক n*log(n) + log(n), কারণ এটি দুটি ফলস্বরূপ দুটি স্বতন্ত্র অপারেশন
পমো_মন্ড্রেগ্যান্টো

27

উপরের উদাহরণটি সাজানোর সাহায্যে কাছাকাছি, তবে স্ট্রিংয়ের ক্ষেত্রে কেবল অনুসন্ধান স্ট্রিং ব্যবহার করুন:

files := []string{"Test.conf", "util.go", "Makefile", "misc.go", "main.go"}
target := "Makefile"
sort.Strings(files)
i := sort.SearchStrings(files, target)
if i < len(files) && files[i] == target {
    fmt.Printf("found \"%s\" at files[%d]\n", files[i], i)
}

https://golang.org/pkg/sort/#SearchStrings


2
এই উত্তরটি নীচের উত্তরের একটি কম তথ্যমূলক কপির পেস্টের মতো দেখায়, যা এই উত্তরের আগে ঘটেছিল।
cytinus

@ সাইটিনাস আপনি কোন উত্তরটি উল্লেখ করছেন? এটিই কেবলমাত্র আমি দেখছি যার উপর ভিত্তি করে sort.SearchStrings
আকিম

1
বড় ফালি দিয়ে বারবার অনুসন্ধানে আমি 100x স্পিডআপ পেয়েছি।
জিওনক্রস

20

ঠিক একই রকম প্রশ্ন ছিল এবং এই থ্রেডের কয়েকটি পরামর্শ চেষ্টা করার সিদ্ধান্ত নিয়েছে।

আমি 3 ধরণের দেখার সর্বোত্তম এবং নিকৃষ্টতম পরিস্থিতিগুলির বেঞ্চমার্ক করেছি:

  • একটি মানচিত্র ব্যবহার করে
  • একটি তালিকা ব্যবহার করে
  • একটি সুইচ স্টেটমেন্ট ব্যবহার করে

এখানে ফাংশন কোড:

func belongsToMap(lookup string) bool {
list := map[string]bool{
    "900898296857": true,
    "900898302052": true,
    "900898296492": true,
    "900898296850": true,
    "900898296703": true,
    "900898296633": true,
    "900898296613": true,
    "900898296615": true,
    "900898296620": true,
    "900898296636": true,
}
if _, ok := list[lookup]; ok {
    return true
} else {
    return false
}
}


func belongsToList(lookup string) bool {
list := []string{
    "900898296857",
    "900898302052",
    "900898296492",
    "900898296850",
    "900898296703",
    "900898296633",
    "900898296613",
    "900898296615",
    "900898296620",
    "900898296636",
}
for _, val := range list {
    if val == lookup {
        return true
    }
}
return false
}

func belongsToSwitch(lookup string) bool {
switch lookup {
case
    "900898296857",
    "900898302052",
    "900898296492",
    "900898296850",
    "900898296703",
    "900898296633",
    "900898296613",
    "900898296615",
    "900898296620",
    "900898296636":
    return true
}
return false
}

সেরা কেস দৃশ্যাবলী তালিকাগুলিতে প্রথম আইটেমটি বাছাই করে, সবচেয়ে খারাপ ক্ষেত্রে হ'ল অযৌক্তিক মান ব্যবহার করে।

ফলাফল এখানে:

BenchmarkBelongsToMapWorstCase-4 2000000 787 ns/op BenchmarkBelongsToSwitchWorstCase-4 2000000000 0.35 ns/op BenchmarkBelongsToListWorstCase-4 100000000 14.7 ns/op BenchmarkBelongsToMapBestCase-4 2000000 683 ns/op BenchmarkBelongsToSwitchBestCase-4 100000000 10.6 ns/op BenchmarkBelongsToListBestCase-4 100000000 10.4 ns/op

স্যুইচটি সমস্তভাবে জিততে পারে, সবচেয়ে খারাপ ক্ষেত্রে সেরা কেসের চেয়ে দ্রুততম হয়। মানচিত্রগুলি সবচেয়ে খারাপ এবং তালিকাটি স্যুইচ করার কাছাকাছি।

সুতরাং নৈতিকটি হ'ল: আপনার যদি একটি স্থিতিশীল, যুক্তিযুক্ত ছোট তালিকা থাকে তবে স্যুইচ স্টেটমেন্টটি যাওয়ার উপায়।


আমি জানি না গো এই কেসটিকে অনুকূল করে কিনা, তবে আপনি যদি তালিকা / মানচিত্রের সূচনাটি পরীক্ষা ফাংশনের বাইরে নিয়ে যান তবে কি এটির কোনও পার্থক্য রয়েছে?
w00t

সাজানো তালিকার তুলনাটি কীভাবে
মাইকেল ড্রপার

স্যুইচ স্টেটমেন্ট :পরিবর্তে কি সম্পর্কে ,? এটি কি দ্রুততর করে তোলে?
টমাস সৌভাজন

আমি caseএকক মামলার পরিবর্তে একাধিক বিবৃতি ব্যবহার করার চেষ্টা করেছি । উভয় ফাংশনের সাথে ফলাফল সংবেদনশীলভাবে একই ibly
টমাস সৌভাজন

7

আর একটি বিকল্প মানচিত্রকে সেট হিসাবে ব্যবহার করছে। আপনি কেবল কীগুলি ব্যবহার করেন এবং মানটি বুলিয়ান এর মতো কিছু হতে পারে যা সর্বদা সত্য। তারপরে আপনি মানচিত্রে কীটি রয়েছে কিনা তা সহজেই পরীক্ষা করতে পারবেন। আপনার যদি কোনও সেটের আচরণের প্রয়োজন হয় তবে আপনি যদি একাধিকবার কোনও মান যুক্ত করেন তবে এটি একবারে সেটটিতে রয়েছে।

এখানে একটি সাধারণ উদাহরণ যেখানে আমি কোনও মানচিত্রের কী হিসাবে এলোমেলো সংখ্যা যুক্ত করি। যদি একই সংখ্যা একাধিকবার উত্থাপিত হয় তবে এটি গুরুত্বপূর্ণ নয়, এটি কেবল একবার চূড়ান্ত মানচিত্রে উপস্থিত হবে। তারপরে আমি একটি সরল ব্যবহার করি যদি মানচিত্রটিতে কী আছে কি না তা পরীক্ষা করে দেখুন।

package main

import (
    "fmt"
    "math/rand"
)

func main() {
    var MAX int = 10

    m := make(map[int]bool)

    for i := 0; i <= MAX; i++ {
        m[rand.Intn(MAX)] = true
    }

    for i := 0; i <= MAX; i++ {
        if _, ok := m[i]; ok {
            fmt.Printf("%v is in map\n", i)
        } else {
            fmt.Printf("%v is not in map\n", i)
        }
    }
}

এখানে এটি খেলার মাঠে রয়েছে


0

এটি পাইথনের "ইন" অপারেটরের প্রাকৃতিক অনুভূতিটি পেতে পারি ততই কাছাকাছি। আপনাকে নিজের ধরণের সংজ্ঞা দিতে হবে। তারপরে আপনি "হ্যাস" এর মতো একটি পদ্ধতি যুক্ত করে সেই ধরণের কার্যকারিতা প্রসারিত করতে পারেন যা আপনার আশা মতো আচরণ করে।

package main

import "fmt"

type StrSlice []string

func (list StrSlice) Has(a string) bool {
    for _, b := range list {
        if b == a {
            return true
        }
    }
    return false
}

func main() {
    var testList = StrSlice{"The", "big", "dog", "has", "fleas"}

    if testList.Has("dog") {
        fmt.Println("Yay!")
    }
}

আমার কাছে একটি ইউটিলিটি লাইব্রেরি রয়েছে যেখানে আমি বেশ কয়েকটি ধরণের টুকরার জন্য কয়েকটি সাধারণ জিনিস যেমন সংজ্ঞা বা আমার নিজস্ব স্ট্রাইক যুক্তগুলি সংজ্ঞায়িত করি।

হ্যাঁ, এটি রৈখিক সময়ে সঞ্চালিত হয়, তবে এটি মূল বিষয় নয়। মুল বক্তব্যটি হ'ল জিজ্ঞাসা করুন এবং শিখুন যে কী সাধারণ ভাষা নির্ধারণ করে এবং তার কী নেই। এটি একটি ভাল অনুশীলন। এই উত্তরটি নির্বোধ বা দরকারী কিনা তা পাঠকের উপর নির্ভর করে।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.