تابع filter (یا Select) در روبی

تابع filter (یا select) یکی از متداول‌ترین توابع برنامه‌نویسی تابعی است که بسیار کاربردی هم است.

مثلا این چند خط کد روبی را

even_numbers = []
[1,2,3,4,5,6].each do |n|
  if n.even?
    even_numbers << n   # append
  end
end
# => [2,4,6]

با استفاده از فیلتر می توان به صورت زیر بازنویسی کرد:

even_numbers = [1,2,3,4,5,6].filter(&:even?)
# => [2,4,6]

خیلی بهتر شد، نه؟

همینطور اگر یک عنصر بخصوصی را بخواهیم (بجای یک collection) می‌توانیم از find. استفاده کنیم.
ضمناً برای نقیض filter یا select تابعی به نام reject وجود دارد که بجای اینکه بر اساس شرط انتخاب کند، نادیده می گیرد.

پ.ن: filter‌ و select جفتشون یک چیز هستند.

6 پسندیده

همین تابع filter در Python

even_numbers = filter(lambda x: x % 2 == 0, range(1, 7))
print(list(even_numbers))
1 پسندیده

همین مجدد در روبی:

even_numbers = (1..6).filter(&:even?) 
# or
even_numbers = (1..6).filter{ |i| i.even? }
p even_numbers

برای همین روبی را دوست دارم، حتی OOPتر از پایتون. به شکل خوبی.

خب حالا ک اینطوره منم اینو واسه Nim مینویسم:

import sequtils

func `[]`(rng: HSlice[int, int],indx: int): int=
  indx + rng.a

func isEven(n: int): bool = 
  n mod 2 == 0

echo (1..6).filterIt it.isEven
# @[2, 4, 6]
1 پسندیده

آخی! چقدر cute :heart_eyes: :star_struck:
یه سری زبان کوچولو موچولو دارن ادای زبان بزرگا رو در میارن :joy::joy::joy:

#کلوژر

;; filter:
(filter even? (range 10))
;;=> (0 2 4 6 8)

(filter #(= (rem % 3) 0) (range 50))
;;=> (0 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48)
;; remove:
(remove pos? [1 -2 2 -1 3 7 0])
;;=> (-2 -1 0)
;; keep:
(keep even? (range 1 10))
;;=> (false true false true false true false true false)

(keep #(if (odd? %) %) (range 10))
;;=> (1 3 5 7 9)

من روبی بلد نیستم ولی فکر کنم فرقشون این باشه که فیلتر، lazy sequence برمیگردونه. حداقل توی کلوژر که اینطوره.

2 پسندیده

تو روبی هیچ فرقی ندارند

Array#filter is an alias for Array#select.

https://apidock.com/ruby/Array/filter

4 پسندیده

اینا یه سری الگوریتم کار با مجموعه ها هستند که خیلی ربطی به زبان نداره، و بنظر نمیاد هیچکدوم کپی از دیگری باشه.

1 پسندیده

منظورم این بود که زبانهای غیر فانکشنال دارن سعی میکنن FP رو پیاده‌سازی کنن.
الآن دیگه همه، یه lambda توی ورژن آخرشون آوردن :smiley:

2 پسندیده

خب هدف قرار دادن راه حل مناسب برای کار روی مجموعه ها هست و سعی میکنن فیچر های فانکشنال هم داشته باشند که همیشه اینطور بوده. بازم بنظر من پیروی از زبان نیست، فقط استفاده از پترن های اثبات شده هست.
یکی از دلایلی که من از روبی خوشم میاد اینه که خیلی میتونه فانکشنال باشه و برعکس پایتون از tail recursion به صورت بهبود یافته پشتیبانی میکنه

2 پسندیده

منم نگفتم از روی کلوژر کپی کردن.
«منظورم این بود که همه دارن سعی میکنن FP رو پیاده سازی کنن»

1 پسندیده

من مخالفت نکردم، فقط توضیح‌اضافه تر دادم

1 پسندیده

همینطور که اینجا هم گفته select توی روبی این کار رو میکنه ولی filter هم بخاطر اینکه یک اسم عمومی و فراگیر برای این تابع هست هم پشتیبانی میکنه.

1 پسندیده

فانکشن select هست و نام مستعارش(Alias) میشه filter.
از این چیزا توی روبی زیاد هست، مثل inject و reduce

1 پسندیده

درود - من ی کتابخونه نوشتم توی Nim که شما استایل فانکشنال مینویسی و استایل impreative اش موقع کامپایل جایگزین میشه.

خوبیش اینه که مقدار هارو توی ی آرایه/لیست/دنباله میانی نمیریزه

توی کد زیر با این کتابخونه اومدم روی کاراکتر های این string پیمایش کردم. استفاده از iterator به نام pairs باعث میشه که به ایندکس اون هم دسترسی داشته باشم.

"hello".pairs >< ifilter[indx, c](indx > 2).imap[_, c](ord c)

یا کد ساده تر مثل:

(1..20) >< ifilter[n](n > 5).imap[n](n * 2)

یا اگر اسم اون متغیر رو بهش ندیم it فرض میشه

(1..20) >< ifilter(it > 5).imap(it * 2)

لینک کتابخونه

1 پسندیده