Filter Like a Pro
Professional darajada filtrlash
Filtr — shartga mos keladigan (yoki mos kelmaydigan) slice elementlarini saqlab qoladi. Arxivlangan foydalanuvchilarni tashlab yuboring. Faqat musbat sonlarni saqlang. Bo'sh qatorlarni chiqarib tashlang.
Klassik andaza — yangi slicaga siklda o'tish:
result := make([]int, 0, len(nums)) // sig'imni oldindan ajratish (batafsili Under the Hood'da)
for _, n := range nums {
if n > 0 {
result = append(result, n)
}
}Go 1.21+ da, slices.DeleteFunc siklni bitta chaqiruvga jamlaydi:
import "slices"
nums = slices.DeleteFunc(nums, func(n int) bool {
return n <= 0
})Ikkita argument:
- •filtrlamoqchi bo'lgan slice.
- •predikat: bitta elementni qabul qilib, uni tashlash uchun
true, saqlash uchunfalseqaytaradigan funksiya.
Misolda, func(n int) bool { return n <= 0 } predikati musbat bo'lmagan har bir elementni tashlab yuboradi.
Funksiya tanasi istalgan mantiqiy ifoda bo'lishi mumkin: solishtirish, o'z funksiyangizga chaqiruv, yoki strings paketidagi HasPrefix yoki Contains kabi yordamchi.
Funksiyani argument sifatida uzatish
slices.DeleteFunc ikkinchi argument sifatida *funksiya* qabul qiladi. Bu — yuqori darajali funksiya (higher-order function): kutubxona iteratsiyani boshqaradi, siz esa qoidani berasiz.
Bu andaza hamma joyda uchraydi: JavaScript'ning arr.filter(fn), Python'ning filter(fn, items), Rust'ning vec.retain(fn). Har safar bir xil g'oya: "nima qilish kerak"ni "qaysi elementlar"dan ajratish.
Odatda inline anonim funksiya berasiz, lekin nomlangani ham ishlaydi:
files := []string{".git", "main.go", ".env", "README.md"}
isHidden := func(name string) bool { return strings.HasPrefix(name, ".") }
files = slices.DeleteFunc(files, isHidden)
// files endi ["main.go", "README.md"]Xotira ajratishga e'tibor bering
Ikkala yondashuv o'xshab ko'rinadi, lekin xotira xatti-harakati boshqacha:
- •Oddiy sikl: yangi tub massiv yaratadi. Kirish o'zgarishsiz qoladi; natija alohida ajratilgan xotira.
- •`slices.DeleteFunc`: yangi xotira ajratmaydi. Omon qolgan elementlarni bir xil massiv ichida oldinga suradi va qisqaroq slice header qaytaradi. Kirish o'zgartiriladi, tashlangan elementlar yo'qoladi.
Shuning uchun qaytish qiymatini doim qaytadan belgilaysiz, va agar asl nusxa buzilmasligi kerak bo'lsa, avval nusxa olishingiz kerak.
>_ Exercise
Nomi temp_ bilan boshlanadigan har bir jadvalni tashlab, qolganlarini qaytaradigan DropTempTables(tables []string) []string funksiyasini yozing.
Misol: DropTempTables([]string{"users", "temp_001", "orders", "temp_cache"}) ["users", "orders"] qaytaradi.
Agar hech qanday nom temp_ bilan boshlanmasa, ro'yxatni o'zgarishsiz qaytaring. Agar har bir nom temp_ bilan boshlansa (yoki kirish bo'sh bo'lsa), bo'sh slice qaytaring.
Stuck? Reveal a hint to help you.
Key Takeaway
Key Takeaway:
Go 1.21+ da predikat bo'yicha o'chirish uchun slices.DeleteFuncni afzal ko'ring. Filtrlash yagona ish bo'lmaganda (elementlarni o'zgartirish, aslini saqlab qolish, yoki har bir element uchun ikkitadan ko'p natijaga bo'lish kerak bo'lganda) aniq siklga murojaat qiling.
NEXT UP
Arrays: The Fixed Sibling
$ go run main.go
Kodingizni ishga tushiring