একটি স্লাইস জন্য পদ্ধতি ধারণ করে


উত্তর:


226

মোস্তফা ইতিমধ্যে চিহ্নিত করেছেন যে এ জাতীয় পদ্ধতি লেখার জন্য ক্ষুদ্র, এবং এমকেবি আপনাকে বাছাই প্যাকেজ থেকে বাইনারি অনুসন্ধান ব্যবহার করার জন্য একটি ইঙ্গিত দিয়েছে। তবে আপনি যদি এর মধ্যে অনেকগুলি চেক অন্তর্ভুক্ত করেন তবে আপনি পরিবর্তে একটি মানচিত্র ব্যবহারের বিষয়টি বিবেচনা করতে পারেন।

value, ok := yourmap[key]আইডিয়ামটি ব্যবহার করে কোনও নির্দিষ্ট মানচিত্র কী উপস্থিত রয়েছে কিনা তা পরীক্ষা করা তুচ্ছ । যেহেতু আপনি মানটির প্রতি আগ্রহী নন, আপনি map[string]struct{}উদাহরণস্বরূপ এটিও তৈরি করতে পারেন । struct{}এখানে খালি ব্যবহার করে সুবিধা হয় যে এটি কোনও অতিরিক্ত স্থানের প্রয়োজন হয় না এবং গো-র অভ্যন্তরীণ মানচিত্রের ধরণটি সেই ধরণের মানের জন্য অনুকূলিত হয়। সুতরাং, map[string] struct{}গো বিশ্বে সেটগুলির জন্য জনপ্রিয় পছন্দ choice


27
আরও মনে রাখবেন, struct{}{}খালি কাঠামোর মান পেতে আপনাকে লিখতে হবে যাতে আপনি যখন কোনও উপাদান যুক্ত করতে চান তখন এটি আপনার মানচিত্রে পাস করতে পারেন। এটি চেষ্টা করে দেখুন, এবং যদি আপনার কোনও সমস্যা হয় তবে নির্দ্বিধায় জিজ্ঞাসা করুন। আপনি যদি মোস্তফার সমাধানটি বুঝতে সহজ হন তবে এটি ব্যবহার করতে পারেন (যদি না আপনার কাছে প্রচুর পরিমাণে ডেটা থাকে)।
tux21b

5
সমাধানটি সহজ, এটি সত্য। তবে রানটাইমের ক্ষেত্রে এ জাতীয় প্রাথমিক কার্যকারিতা যুক্ত করতে কী লাগে? গিথুব-এ গো রেপোতে আমি এ জাতীয় সমস্যাগুলি পাই নি। এটি দুঃখজনক এবং আশ্চর্যজনক।
ইগর পেট্রোভ

1
কিভাবে map[string] boolতুলনা করে map[string] struct{}map[string] struct{}হ্যাকের মতো মনে হচ্ছে বিশেষত একটি খালি কাঠামো সূচনা করছেstruct {}{}
ভাদসাম্বার

@ ইগরপেট্রভ সম্মত হয়েছেন, আমি অবাক হয়েছি যে এরকম একটি প্রাথমিক বৈশিষ্ট্য ইতিমধ্যে রানটাইমে নেই।
jcollum

180

না, এই জাতীয় পদ্ধতির অস্তিত্ব নেই, তবে এটি লিখতে তুচ্ছ:

func contains(s []int, e int) bool {
    for _, a := range s {
        if a == e {
            return true
        }
    }
    return false
}

আপনি যদি একটি মানচিত্র ব্যবহার করতে পারেন যদি সেই অনুসন্ধানটি আপনার কোডের একটি গুরুত্বপূর্ণ অংশ, তবে মানচিত্রেরও ব্যয় হয়।


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


2
@ অ্যালেক্স লকউড এই আসলে ইন্টারফেসের সাথে কাজ করবে?
অরি ব্যান্ড

101
তুচ্ছ == কোডের 1 টি লুপ 1 লুপ 1 শাখা যদি বিবৃতি এবং 1 তুলনা করে? আমি মনে করি আমি এখানে কিছু মিস করছি ...
টোথামারিও

3
তবে কেন গো কোর এগুলিকে যুক্ত করবেন না?
লুনা লাভগুড


11

এর পরিবর্তে একটি ব্যবহার করা slice, এর mapচেয়ে ভাল সমাধান হতে পারে।

সাধারণ উদাহরণ:

package main

import "fmt"


func contains(slice []string, item string) bool {
    set := make(map[string]struct{}, len(slice))
    for _, s := range slice {
        set[s] = struct{}{}
    }

    _, ok := set[item] 
    return ok
}

func main() {

    s := []string{"a", "b"}
    s1 := "a"
    fmt.Println(contains(s, s1))

}

http://play.golang.org/p/CEG6cu4JTf


34
এটির বর্তমান আকারে এই কোডটি কোনও সুবিধা দেয় না, যেহেতু আপনি যদি কেবল একবার এটি ব্যবহার করতে যাচ্ছেন তবে কোনও স্লাইস থেকে মানচিত্র তৈরির কোনও লাভ নেই। - দরকারী হতে, এই কোড পরিবর্তে একটি ফাংশন প্রদান করা উচিত sliceToMapযা সমস্ত প্রস্তুতি করে। এর পরে, মানচিত্রটি অনুসন্ধান করা তুচ্ছ এবং দক্ষ।
রোল্যান্ড ইলিগ

9

সাজানোর প্যাকেজ বিল্ডিং ব্লক প্রদান করে যদি আপনার ফালি অনুসারে বাছাই করা হয় অথবা আপনি তা বাছাই করতে ইচ্ছুক।

input := []string{"bird", "apple", "ocean", "fork", "anchor"}
sort.Strings(input)

fmt.Println(contains(input, "apple")) // true
fmt.Println(contains(input, "grow"))  // false

...

func contains(s []string, searchterm string) bool {
    i := sort.SearchStrings(s, searchterm)
    return i < len(s) && s[i] == searchterm
}

SearchStringফিরে আসার প্রতিশ্রুতি দেয় the index to insert x if x is not present (it could be len(a)), সুতরাং এটির একটি চেক প্রকাশ করে যে স্ট্রিংটি সাজানো টুকরা রয়েছে কিনা।


সময়ের নিরিখে, নিয়মিত অনুসন্ধান হয় O(n)এবং এই সমাধানটি এটি তৈরি করে O(n*log(n))
plesiv

@ প্লিজিভ এটি বাইনারি অনুসন্ধান, এএএফআইএসস। এটি ও (লগ এন) করে না?
হেনরিক এ্যাসটেড সেরেনসেন

হ্যাঁ, বাইনারি-অনুসন্ধান এবং ফাংশন containsহয় O(log(n)), কিন্তু সামগ্রিক পন্থা O(n*log(n))সাজানোর কারণে।
প্লিজিভ

3

আপনি ব্যবহার করতে পারেন প্রতিফলিত একটি ইন্টারফেস যার কংক্রিট টাইপ একটি ফালি হয় পুনরুক্তি উপর প্যাকেজ:

func HasElem(s interface{}, elem interface{}) bool {
    arrV := reflect.ValueOf(s)

    if arrV.Kind() == reflect.Slice {
        for i := 0; i < arrV.Len(); i++ {

            // XXX - panics if slice element points to an unexported struct field
            // see https://golang.org/pkg/reflect/#Value.Interface
            if arrV.Index(i).Interface() == elem {
                return true
            }
        }
    }

    return false
}

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


3
নিশ্চিত আপনি প্রতিবিম্ব প্যাকেজটি ব্যবহার করতে পারেন তবে কেবল তাই আপনি পারেন, তার মানে এই নয় যে আপনার উচিত। প্রতিবিম্ব খুব ব্যয়বহুল।
জাস্টিন ওহমস

3

যদি কোনও চাবির উপর ভিত্তি করে আইটেম সন্ধানের জন্য মানচিত্র ব্যবহার করা সম্ভব না হয় তবে আপনি দেবদারু সরঞ্জামটি বিবেচনা করতে পারেন । গডেরিভ আপনার কোডকে পাঠযোগ্য ও দক্ষ উভয় করে তোলে এমন একটি পদ্ধতির সমন্বিত একটি নির্দিষ্ট পদ্ধতি প্রয়োগ করে rates

উদাহরণ;

type Foo struct {
    Field1 string
    Field2 int
} 

func Test(m Foo) bool {
     var allItems []Foo
     return deriveContainsFoo(allItems, m)
}

ডেরিভ কনটেনসফু পদ্ধতিটি তৈরি করতে:

  • এর সাথে গডেরিভ ইনস্টল করুন go get -u github.com/awalterschulze/goderive
  • goderive ./...আপনার ওয়ার্কস্পেস ফোল্ডারে চালান

এই পদ্ধতিটি ডেরিভ কন্টেইনগুলির জন্য উত্পন্ন হবে:

func deriveContainsFoo(list []Foo, item Foo) bool {
    for _, v := range list {
        if v == item {
            return true
        }
    }
    return false
}

গডেরিভের কার্যক্ষম প্রোগ্রামিং শৈলীতে যেতে প্রয়োগ করার জন্য বেশ কয়েকটি দরকারী সহায়ক সহায়তার পদ্ধতি রয়েছে।


2
func Contain(target interface{}, list interface{}) (bool, int) {
    if reflect.TypeOf(list).Kind() == reflect.Slice || reflect.TypeOf(list).Kind() == reflect.Array {
        listvalue := reflect.ValueOf(list)
        for i := 0; i < listvalue.Len(); i++ {
            if target == listvalue.Index(i).Interface() {
                return true, i
            }
        }
    }
    if reflect.TypeOf(target).Kind() == reflect.String && reflect.TypeOf(list).Kind() == reflect.String {
        return strings.Contains(list.(string), target.(string)), strings.Index(list.(string), target.(string))
    }
    return false, -1
}

2

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

type Identifiable interface{
    GetIdentity() string
}

func IsIdentical(this Identifiable, that Identifiable) bool{
    return (&this == &that) || (this.GetIdentity() == that.GetIdentity())
}

func contains(s []Identifiable, e Identifiable) bool {
    for _, a := range s {
        if IsIdentical(a,e) {
            return true
        }
    }
    return false
}

1
"আপনাকে অন্যান্য ভাষায় যা করতে হবে তার চেয়ে বেশি কিছু নয়" সত্যই সত্য নয় - যেমন সি # Contains()তে কার্যকর হয় List<T>, সুতরাং আপনাকে কেবল Equals()সেই কাজের জন্যই প্রয়োগ করতে হবে ।
জর্জি

1

এই উত্তরগুলি থেকে সমাধানগুলি সহ আমি একটি খুব সাধারণ মানদণ্ড তৈরি করেছি।

https://gist.github.com/NorbertFenk/7bed6760198800207e84f141c41d93c7

এটি সত্যিকারের মানদণ্ড নয় কারণ প্রাথমিকভাবে, আমি অনেকগুলি উপাদান সন্নিবেশ করিনি তবে এটি কাঁটাচামচ এবং পরিবর্তন করতে নির্দ্বিধায়।


আমি এটি সম্পর্কে ভেবেছিলাম কিন্তু আমার মেশিনটি এতটা শক্তিশালী না হওয়ার কারণে এটি এতটা প্রতিনিধিত্বমূলক নয়।
এফ। নরবার্ট

0

এটি কিছুটা 'হ্যাকি' হিসাবে বিবেচিত হতে পারে তবে স্লাইসের আকার এবং বিষয়বস্তুর উপর নির্ভর করে আপনি একসাথে স্লাইসে যোগ দিতে পারেন এবং স্ট্রিং অনুসন্ধান করতে পারেন।

উদাহরণস্বরূপ আপনার একক শব্দের মানযুক্ত স্লাইস রয়েছে (যেমন "হ্যাঁ", "না", "হতে পারে")। এই ফলাফলগুলি একটি স্লাইসে সংযুক্ত করা হয়। যদি আপনি এই স্লাইসে কোনও "সম্ভবত" ফলাফল রয়েছে কিনা তা পরীক্ষা করতে চান তবে আপনি ব্যবহার করতে পারেন

exSlice := ["yes", "no", "yes", "maybe"]
if strings.Contains(strings.Join(exSlice, ","), "maybe") {
  fmt.Println("We have a maybe!")
}

এটি কীভাবে উপযুক্ত তা তার সদস্যদের স্লাইস আকার এবং দৈর্ঘ্যের উপর নির্ভর করে। বৃহত্তর টুকরোগুলি বা দীর্ঘ মানগুলির জন্য কর্মক্ষমতা বা উপযুক্ততার সমস্যা থাকতে পারে তবে সীমাবদ্ধ আকার এবং সাধারণ মানগুলির ছোট ছোট টুকরাগুলির জন্য এটি পছন্দসই ফলাফল অর্জনের জন্য একটি বৈধ এক-লাইনার।


অবস্থা যেখানে উপাদান অনুরূপ টেক্সট কিন্তু ঠিক একই আছে তাদের জন্য কাজ করবে নাexSlice := ["yes and no", "maybe", "maybe another"]
Raees ইকবাল

দ্রুত এবং নোংরা ওয়ান-লাইনারের সমাধান অর্জনের জন্য এটি একটি দুর্দান্ত উপায়। আপনার কেবল একটি দ্ব্যর্থহীন সীমানা (কমা হতে পারে) প্রয়োজন এবং উভয় স্ট্রিং বন্ধনী ব্যবহার করার জন্য অতিরিক্ত কাজ করা দরকার ","+strings.Join(exSlice,",")+","",maybe,"
:,

-1

গো শৈলী:

func Contains(n int, match func(i int) bool) bool {
    for i := 0; i < n; i++ {
        if match(i) {
            return true
        }
    }
    return false
}


s := []string{"a", "b", "c", "o"}
// test if s contains "o"
ok := Contains(len(s), func(i int) bool {
    return s[i] == "o"
})

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