تابع 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 Likes

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

even_numbers = filter(lambda x: x % 2 == 0, range(1, 7))
print(list(even_numbers))
1 Likes

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

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 Likes

آخی! چقدر 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 Likes

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

Array#filter is an alias for Array#select.

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

4 Likes

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

1 Likes

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

2 Likes

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

2 Likes

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

1 Likes

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

1 Likes

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

1 Likes

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

1 Likes