এক স্লাইসে উপাদান মুছুন


139
func main() {
    a := []string{"Hello1", "Hello2", "Hello3"}
    fmt.Println(a)
    // [Hello1 Hello2 Hello3]
    a = append(a[:0], a[1:]...)
    fmt.Println(a)
    // [Hello2 Hello3]
}

অ্যাপেন্ড ফাংশনটির সাথে এই মুছে ফেলা কৌশলটি কীভাবে কাজ করে?

দেখে মনে হবে এটি প্রথম উপাদানটির আগে সমস্ত কিছু দখল করছে (খালি অ্যারে)

তারপরে প্রথম উপাদানটির পরে সবকিছু সংযোজন (অবস্থান শূন্য)

... (বিন্দু বিন্দু) কী করবে?



3
কেন ভাষা অনুমান একবার দেখুন? ...সেখানে বিস্তারিত ব্যাখ্যা করা হয়?
ভোলকার

9
একদিকে, একেবারে সত্য ( golang.org/ref/spec , সবাই); অন্যদিকে পাইথোনিস্টাস ইত্যাদি স্থানান্তরিত করার জন্য এই প্রজ্ঞাগুলি সম্পর্কে যথেষ্টই অপরিচিত আছে যা অন্যের সন্ধানের জন্য সেখানে কোনও ব্যাখ্যা দিতে আমার আপত্তি নেই।
twotwotwo

উত্তর:


276

aস্লাইসটি কোথায় এবং iআপনি যে উপাদানটি মুছতে চান তার সূচক:

a = append(a[:i], a[i+1:]...)

... গো-এ বিচিত্র যুক্তিগুলির জন্য বাক্য গঠন।

মূলত, একটি ফাংশন সংজ্ঞায়িত করার সময় এটি সমস্ত ধরণের আর্গুমেন্ট রাখে যা আপনি সেই ধরণের একটি টুকরোতে প্রবেশ করেন। এটি করে আপনি যতগুলি আর্গুমেন্ট চান তা পাস করতে পারেন (উদাহরণস্বরূপ, fmt.Printlnআপনি যতটা আর্গুমেন্ট নিতে পারেন)।

এখন, কোনও ফাংশন কল করার সময় , ...বিপরীতটি করে: এটি একটি স্লাইসকে প্যাক করে আলাদা আলাদা আর্গুমেন্ট হিসাবে তাদেরকে একটি ভেরিয়্যাডিক ফাংশনে স্থান দেয়।

সুতরাং এই লাইনটি কি করে:

a = append(a[:0], a[1:]...)

মূলত:

a = append(a[:0], a[1], a[2])

এখন, আপনি ভাবছেন, কেন শুধু করবেন না

a = append(a[1:]...)

ঠিক আছে, ফাংশন সংজ্ঞা appendহয়

func append(slice []Type, elems ...Type) []Type

সুতরাং প্রথম আর্গুমেন্টটি সঠিক ধরণের একটি টুকরা হতে হবে, দ্বিতীয় যুক্তিটি বৈচিত্র্যময়, তাই আমরা একটি খালি স্লাইসে পাস করি এবং তারপরে বাকী স্লাইসটি প্যাকেজটি আর্গুমেন্টগুলিতে পূরণ করতে পারি।


35
আমি যদি স্লাইস থেকে শেষ উপাদান হয় তবে আপনি কি পরিসীমা ব্যতিক্রমের বাইরে চলে যাবেন না? a = append(a[:i], a[i+1:]...)
থিশাইহাই

5
@ ডেভসি আমার প্রকল্পে আমার স্লাইসগুলি নিয়ে কাজ করার সময় আমি এই ত্রুটিটি পেয়েছি: /
টাইগুই 7

3
@ টাইগুই 7 টি অনুমান থেকে: "অ্যারে বা স্ট্রিংয়ের জন্য সূচকগুলি 0 <= নিম্ন <= উচ্চ <= লেন (ক), যদি না হয় তবে তারা সীমার বাইরে থাকে" " হতে পারে আপনার ক্ষেত্রে উচ্চ <কম; সেক্ষেত্রে আপনি ত্রুটি পাবেন। ( golang.org/ref/spec# স্লাইস_ এক্সপ্রেসনস )
এমএলজি

2
এর পারফরম্যান্স কেমন? আমি গুরুত্ব সহকারে আশা করি এটি হুডের নীচে সম্পূর্ণ নতুন টুকরো তৈরি করছে না ..
জুনাস.ফি

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

42

দুটি বিকল্প রয়েছে:

উত্তর: আপনি অ্যারে অর্ডার বজায় রাখা সম্পর্কে যত্নশীল:

a = append(a[:i], a[i+1:]...)
// or
a = a[:i+copy(a[i:], a[i+1:])]

বি: আপনি ধরে রাখার অর্ডারটি যত্ন নেবেন না (এটি সম্ভবত দ্রুত):

a[i] = a[len(a)-1] // Replace it with the last one. CAREFUL only works if you have enough elements.
a = a[:len(a)-1]   // Chop off the last one.

যদি আপনার অ্যারে পয়েন্টারগুলির হয় তবে ইমপ্লিকেশনগুলি পুনরায় মেমরি ফাঁস দেখতে লিঙ্কটি দেখুন।

https://github.com/golang/go/wiki/SliceTricks


এটি আকর্ষণীয়, তবে সত্যই প্রশ্নের উত্তর দিচ্ছে না
ব্রায়ান

এটি দুর্দান্ত, তবে এটি যদি অ্যারেতে থাকা একমাত্র উপাদানটি মুছতে পারে তবে আরও ভাল হত
নাগুইব ইহাব

2
কেবল একটি মাথা আপ, খ থেকে প্রথমটি ব্যবহারের চেষ্টা করা (শেষ উপাদানটি দিয়ে প্রতিস্থাপন) স্পষ্টতই কাজ করে না যদি আপনি স্লাইস লোলের শেষ উপাদানটি অপসারণ করার চেষ্টা করছেন
সাইরেন্স

13

বরং এ সূচকের চিন্তা চেয়ে [a:], - [:b]- এবং [a:b]উপাদান সূচকের হিসাবে -notations, প্রায় ফাঁক সূচকের হিসেবে এবং উপাদানের মধ্যে তাদের মনে ইন্ডেক্স ফাঁক দিয়ে শুরু 0উপাদান হিসেবে ইন্ডেক্স সামনে 0

এখানে চিত্র বর্ণনা লিখুন

কেবল নীল সংখ্যার দিকে তাকালে, কী চলছে তা দেখতে অনেক সহজ: [0:3]সবকিছুকে ঘিরে রয়েছে, [3:3]খালি রয়েছে এবং [1:2]ফলন হবে {"B"}। তারপরে [a:]কেবল সংক্ষিপ্ত সংস্করণটি [a:len(arrayOrSlice)], [:b]এর সংক্ষিপ্ত সংস্করণ [0:b]এবং [:]এর সংক্ষিপ্ত সংস্করণ [0:len(arrayOrSlice)]। পরেরটি সাধারণত প্রয়োজনের সময় একটি অ্যারেটিকে একটি টুকরোতে পরিণত করতে ব্যবহৃত হয়।


1
এই কারণেই সব রকম উত্তর "না" themihai এর সাহায্য করে মন্তব্য ডেভ এর উপর উত্তর উল্লেখ, [আমি + 1:] এমনকি যখন ith উপাদান উল্লেখ: play.golang.org/p/E0lQ3jPcjX5
নিক পি

5

... হ'ল বিবিধ যুক্তিগুলির জন্য বাক্য গঠন

আমি মনে করি এটি স্লাইস ব্যবহার করে কম্পাইলার দ্বারা প্রয়োগ করা হয়েছে ( []Type)ঠিক যেমন ফাংশন সংযোজন:

func append(slice []Type, elems ...Type) []Type

আপনি যখন "সংযোজন" তে "এলেমস" ব্যবহার করেন, আসলে এটি একটি স্লাইস ([] প্রকার)। সুতরাং " a = append(a[:0], a[1:]...)" এর অর্থ " a = append(a[0:0], a[1:])"

a[0:0] একটি টুকরা যা কিছুই নেই

a[1:] "হ্যালো 2 হ্যালো 3"

এটা এভাবে কাজ করে


2
a[0:0]nil0 দৈর্ঘ্যের এক টুকরো নয় । a[0:0]হবে শুধুমাত্র হতে nilযদি aহয় nil
আইচজা

5

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

পুরানো উত্তর:

chars := []string{"a", "a", "b"}

for i, v := range chars {
    fmt.Printf("%+v, %d, %s\n", chars, i, v)
    if v == "a" {
        chars = append(chars[:i], chars[i+1:]...)
    }
}
fmt.Printf("%+v", chars)

প্রত্যাশিত:

[a a b], 0, a
[a b], 0, a
[b], 0, b
Result: [b]

আসল:

// Autual
[a a b], 0, a
[a b], 1, b
[a b], 2, b
Result: [a b]

সঠিক উপায় (সমাধান):

chars := []string{"a", "a", "b"}

for i := 0; i < len(chars); i++ {
    if chars[i] == "a" {
        chars = append(chars[:i], chars[i+1:]...)
        i-- // form the remove item index to start iterate next item
    }
}

fmt.Printf("%+v", chars)

সূত্র: https://dinolai.com/notes/golang/golang-delete-slice-item-in-range-problem.html


3

গোলংয়ের উইকিতে এটি স্লাইসের জন্য কিছু কৌশল দেখায়, স্লাইস থেকে কোনও উপাদান মুছুন।

লিঙ্ক: লিঙ্কের বিবরণ এখানে লিখুন

উদাহরণস্বরূপ, একটি হ'ল স্লাইস যা আপনি সংখ্যা i উপাদানটি মুছতে চান।

a = append(a[:i], a[i+1:]...)

অথবা

a = a[:i+copy(a[i:], a[i+1:])]
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.