কী দ্বারা মান মানগুলি বাছাই করুন


96

কোডটিতে প্রত্যাশিত মানচিত্রের মাধ্যমে পুনরাবৃত্তি করার সময়, টপিক ফাংশন দিয়ে ফিরে আসে, কীগুলি ক্রম হিসাবে প্রদর্শিত হচ্ছে না।

কীগুলি কীভাবে মানচিত্রকে ক্রমান্বয়ে / সাজানোর জন্য পেতে পারি যাতে কীগুলি ক্রমযুক্ত হয় এবং মানগুলি সামঞ্জস্য হয়?

কোডটি এখানে ।


উত্তর:


160

যান ব্লগ: যান ক্রিয়াটি মানচিত্র একটি চমৎকার ব্যাখ্যা রয়েছে।

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

উদাহরণস্বরূপ কোডটির আমার পরিবর্তিত সংস্করণটি এখানে: http://play.golang.org/p/dvqcGPYy3-

package main

import (
    "fmt"
    "sort"
)

func main() {
    // To create a map as input
    m := make(map[int]string)
    m[1] = "a"
    m[2] = "c"
    m[0] = "b"

    // To store the keys in slice in sorted order
    keys := make([]int, len(m))
    i := 0
    for k := range m {
        keys[i] = k
        i++
    }
    sort.Ints(keys)

    // To perform the opertion you want
    for _, k := range keys {
        fmt.Println("Key:", k, "Value:", m[k])
    }
}

আউটপুট:

Key: 0 Value: b
Key: 1 Value: a
Key: 2 Value: c

41
এটি এর সাহায্যে উন্নত হতে পারে keys := make([]int, len(m))এবং তারপরেkeys[i] = kappend
jpillora

18

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

তারপরে আপনাকে যা করতে হবে তা হ'ল কীগুলি টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো মধ্যে বিভাজক:

var m map[keyType]valueType
keys := sliceOfKeys(m) // you'll have to implement this
for _, k := range keys {
    v := m[k]
    // k is the key and v is the value; do your computation here
}

অপেক্ষা স্লাইসগুলি একটি অ্যারের অংশ। আমি কীভাবে মানচিত্রে কেবল কীগুলির একটি টুকরো তৈরি করব?
গ্রামে.নিনজা

4
গো-তে, "স্লাইস" শব্দটি এমন একটি ডেটা স্ট্রাকচারকে বোঝায় যা মূলত জাভা অ্যারেগুলির সাথে সমান। এটি কেবল একটি পরিভাষার সমস্যা। কীগুলি পাওয়ার জন্য, আপনাকে স্পষ্টভাবে মানচিত্রের উপরে সীমাবদ্ধ করতে হবে এবং আপনি যেমন যান তেমন একটি স্লাইস তৈরি করতে হবে: play.golang.org/p/ZTni0o19Lr
জোশল্ফ

আহ ঠিক আছে. আমাকে শেখানোর জন্য ধন্যবাদ. এখন, এটি সমস্ত ছদ্মবেশটি পরেও সমস্ত বিতর্কিত হয়। play.golang.org/p/K2y3m4Zzqd কীভাবে আমি এটি বিকল্পে যাতে এটি যাতে ক্রমযুক্ত হয়?
গ্রামে.নিনজা

4
আপনার ফিরে আসা স্লাইসটি বাছাই করতে হবে (বা, বিকল্প হিসাবে, এটি ফেরার আগে মানচিত্র কীগুলিতে বাছাই করুন)। আপনি বাছাই প্যাকেজ চেক করতে চাইবেন ।
জোশল্ফ

15

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

func main() {
    m := map[int]int{3: 5, 2: 4, 1: 3}
    fmt.Println(m)

    // In Go 1.12+
    // Output: map[1:3 2:4 3:5]

    // Before Go 1.12 (the order was undefined)
    // map[3:5 2:4 1:3]
}

পরীক্ষাগুলি সহজ করার জন্য মানচিত্রগুলি এখন কী-সাজানো ক্রমে মুদ্রিত হয়। আদেশের নিয়মগুলি হ'ল:

  • প্রযোজ্য হলে, শূন্যের তুলনা কম হয়
  • ইনটস, ফ্লোটস এবং স্ট্রিংগুলি <দ্বারা অর্ডার করে
  • NaN নন-নন ফ্লোটের চেয়ে কম তুলনা করে
  • সত্য সত্য আগে মিথ্যা তুলনা
  • কমপ্লেক্স বাস্তবের সাথে তুলনা করে, তারপরে কাল্পনিক
  • পয়েন্টারগুলি মেশিনের ঠিকানার সাথে তুলনা করে
  • চ্যানেল মানগুলি মেশিনের ঠিকানার সাথে তুলনা করে
  • স্ট্রাক্টগুলি প্রতিটি ক্ষেত্রকে ঘুরে দাঁড়ায়
  • অ্যারেগুলি প্রতিটি উপাদানকে পালাক্রমে তুলনা করে
  • ইন্টারফেসের মানগুলি প্রথমে প্রতিবিম্বের মাধ্যমে তুলনা করে। কংক্রিটের ধরণের বর্ণনা দিয়ে টাইপ করুন এবং তারপরে পূর্ববর্তী নিয়মে বর্ণিত কংক্রিট মান দ্বারা।

মানচিত্র প্রিন্ট করার সময়, NaN এর মতো অ-রিফ্লেক্সিভ মূল মানগুলি আগে হিসাবে প্রদর্শিত হয়েছিল <nil>। এই প্রকাশের হিসাবে, সঠিক মানগুলি মুদ্রিত হয়।

এখানে আরও পড়ুন


9
এটি কেবলমাত্র এফএমটি প্যাকেজ এবং মুদ্রণের ক্ষেত্রে প্রযোজ্য বলে মনে হচ্ছে। প্রশ্নটি জিজ্ঞাসা করে যে কীভাবে একটি মানচিত্রকে বাছাই করা হয়, কীভাবে সাজানো মানচিত্রটি প্রিন্ট করা যায়?
টিম

4
তিনি খেলার মাঠের লিঙ্কটি ভাগ করেছেন। সেখানে তিনি কেবল একটি মানচিত্র প্রিন্ট করেন।
Inanc Gumus

2

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

উদাহরণ:

package main

import (
    "fmt"
    "sort"
)

type myIntMap map[int]string

func (m myIntMap) sort() (index []int) {
    for k, _ := range m {
        index = append(index, k)
    }
    sort.Ints(index)
    return
}

func main() {
    m := myIntMap{
        1:  "one",
        11: "eleven",
        3:  "three",
    }
    for _, k := range m.sort() {
        fmt.Println(m[k])
    }
}

একাধিক মানচিত্রের প্রকারের সাথে প্রসারিত খেলার মাঠের উদাহরণ

গুরুত্বপূর্ণ তথ্য

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

mutex.Lock()
for _, k := range m.sort() {
    fmt.Println(m[k])
}
mutex.Unlock()

1

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

মূল প্রকার Kএবং মান প্রকার সহ একটি মানচিত্র দেওয়া হয়েছে , যা নীচে এবং নীচে Vউপস্থাপন করা হয় , সাধারণ সাজানোর ক্রিয়াকলাপটি এই গো-কোড টেম্পলেটটির মতো দেখতে পারে (যা গো সংস্করণ 1 যেমনটি সমর্থন করে না):<K><V>

/* Go apparently doesn't support/allow 'interface{}' as the value (or
/* key) of a map such that any arbitrary type can be substituted at
/* run time, so several of these nearly-identical functions might be
/* needed for different key/value type combinations. */
func sortedMap<K><T>(m map[<K>]<V>, f func(k <K>, v <V>)) {
    var keys []<K>
    for k, _ := range m {
        keys = append(keys, k)
    }
    sort.Strings(keys)  # or sort.Ints(keys), sort.Sort(...), etc., per <K>
    for _, k := range keys {
        v := m[k]
        f(k, v)
    }
}

তারপরে এটিকে ইনপুট মানচিত্র এবং একটি ফাংশন ( (k <K>, v <V>)এটির ইনপুট আর্গুমেন্ট হিসাবে গ্রহণ ) দিয়ে কল করুন যা মানচিত্রের উপাদানগুলিকে সাজানো-কী ক্রমে বলা হয় in

সুতরাং, মঙ্গু পোস্ট করা উত্তরে কোডের একটি সংস্করণ এর মতো দেখাবে:

package main

import (
    "fmt"
    "sort"
)

func sortedMapIntString(m map[int]string, f func(k int, v string)) {
    var keys []int
    for k, _ := range m {
        keys = append(keys, k)
    }
    sort.Ints(keys)
    for _, k := range keys {
        f(k, m[k])
    }
}

func main() {
    // Create a map for processing
    m := make(map[int]string)
    m[1] = "a"
    m[2] = "c"
    m[0] = "b"

    sortedMapIntString(m,
        func(k int, v string) { fmt.Println("Key:", k, "Value:", v) })
}

sortedMapIntString()ফাংশন কোন জন্য পুনরায় ব্যবহার করা যেতে পারে map[int]string(অভিমানী একই সাজানোর ক্রম আকাঙ্ক্ষিত হয়), কোড মাত্র দুই লাইনে প্রতিটি ব্যবহারের রাখা।

ডাউনসাইড অন্তর্ভুক্ত:

  • প্রথম শ্রেণীর হিসাবে ফাংশন ব্যবহারে বেআইনী লোকদের পক্ষে পড়া আরও কঠিন
  • এটি ধীর হতে পারে (আমি পারফরম্যান্সের তুলনা করি না)

অন্যান্য ভাষার বিভিন্ন সমাধান রয়েছে:

  • যদি <K>এবং <V>(কী এবং মানের জন্য প্রকারের বোঝাতে) ব্যবহারটি কিছুটা পরিচিত দেখায় তবে সেই কোড টেম্পলেটটি সি ++ টেম্পলেটগুলির মতো ভয়ঙ্কর নয়।
  • ক্লোজার এবং অন্যান্য ভাষাগুলি মৌলিক ডেটা ধরণের হিসাবে বাছাই করা মানচিত্রকে সমর্থন করে।
  • যদিও আমি কোনও উপায়েই জানি না যে গো rangeপ্রথম শ্রেণীর ধরণের তৈরি করে যাতে এটি কোনও কাস্টম ordered-range( rangeমূল কোডের পরিবর্তে) দ্বারা প্রতিস্থাপিত হতে পারে , তবে আমি মনে করি কিছু অন্যান্য ভাষাগুলি পুনরাবৃত্তি সরবরাহ করে যা এটি সম্পাদন করার পক্ষে যথেষ্ট শক্তিশালী are জিনিস।

4
নবীনদের জন্য এটি উল্লেখ করার মতো হতে পারে যে গো <দ>> <ভি> বাক্য গঠনটি সমর্থিত নয়।
justinhj

আপনার কোডটি জানিয়েছে: যান দৃশ্যত কোনও মানচিত্রের মান (বা কী) হিসাবে 'ইন্টারফেস {}' সমর্থন করে না / অনুমতি দেয় না । এটা সত্য নয়। var m map[interface{}]interface{}সম্পূর্ণ আইনী। খেলার মাঠ
টিম

আসলে, মন্তব্য মন্তব্য ব্লক Go apparently doesn't support/allow 'interface{}' as the value (or key) of a map such that any arbitrary type can be substituted at run time। যদি (ব্যবহার unsafeবা অনুরূপ ব্যতীত অন্য ) আপনি রান সময়ে কীভাবে একটি স্বেচ্ছাসেবীর প্রকারকে প্রতিস্থাপন করতে পারেন তা এইভাবে দেখাতে পারেন, সুতরাং এটি একটি একক জেনেরিক সাজানোর রুটিন সরবরাহ করে, দুর্দান্ত! (কয়েক মাস আগে আমি নিজেই এটি বুঝতে পারি না))
জেমস ক্রেগ বারলি

0

এটি আপনাকে মানচিত্র বাছাই করার কোডের উদাহরণ সরবরাহ করে। মূলত এগুলিই তারা সরবরাহ করে:

var keys []int
for k := range myMap {
    keys = append(keys, k)
}
sort.Ints(keys)

// Benchmark1-8      2863149           374 ns/op         152 B/op          5 allocs/op

এবং এটির পরিবর্তে আমি এটি ব্যবহার করার পরামর্শ দেব :

keys := make([]int, 0, len(myMap))
for k := range myMap {
    keys = append(keys, k)
}
sort.Ints(keys)

// Benchmark2-8      5320446           230 ns/op          80 B/op          2 allocs/op

এই গো খেলার মাঠে পুরো কোডটি পাওয়া যাবে ।

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