আজ আমরা slice_before, slice_when এবং slice_after নিয়ে আলোচনা করব। আপনি যখন একটি অ্যারে বা অন্য যেকোনো এনumerable-এর আইটেমগুলো.any arbitrary criteria-র ভিত্তিতে গ্রুপ করতে চান, তখন এই মেথডগুলো অত্যন্ত উপকারী।
আপনি সম্ভবত Array#slice নিয়ে পরিচিত। এটি একটি অ্যারের একটি সাবসেট বের করতে দেয় ইন্ডেক্সের রেঞ্জের ভিত্তিতে:
a = ["a", "b", "c"]
a.slice(1, 2) # => ["b", "c"]
এটি উপকারী, কিন্তু এনumerable-এর সাথে ব্যবহার করা যায় না, কারণ এনumerable-এর ইন্ডেক্স নেই।
slice_before, slice_when এবং slice_after মেথডগুলো ইন্ডেক্সের ওপর নির্ভর করে না—তাই আপনি যেকোনো এনumerable-এর সাথে সেগুলো ব্যবহার করতে পারেন। চলুন দেখি!
Enumerable#slice_before ব্যবহার
Enumerable#slice_before একটি এনumerable কে גרুপে ভাগ করে ম্যাচ হওয়ার ঠিক আগের পয়েন্টে।
ম্যাচ করা হয় === অপারেটর দিয়ে, যার মানে আপনি সব ধরনের জিনিস ম্যাচ করতে পারেন।
ভ্যালু ম্যাচ
আপনি একটি একক ভ্যালু ম্যাচ করতে পারেন। এটি স্বভাবতঃ স্বচ্ছ। :)
a = ["a", "b", "c"]
a.slice_before("b").to_a # => [["a"], ["b", "c"]]
রেগুলার এক্সপ্রেশন ম্যাচ
আপনি জটিল টেক্সচুয়াল ম্যাচিংয়ের জন্য রেগুলার এক্সপ্রেশন ব্যবহার করতে পারেন।
a = ["000", "b", "999"]
a.slice_before(/[a-z]/).to_a # => [["000"], ["b", "999"]]
রেঞ্জ ম্যাচ
আপনি যদি নম্বর নিয়ে কাজ করেন, তবে আপনি একটি রেঞ্জের ভিত্তিতে অ্যারেটি স্লাইস করতে পারেন।
a = [100, 200, 300]
a.slice_before(150..250).to_a # => [[100], [200, 300]]
ক্লাস ম্যাচ
এটি আপনাকে কিছুটা অদ্ভুত লাগতে পারে, কিন্তু এটি === অপারেটরের আচরণের সাথে সম্পূর্ণ সামঞ্জস্যপূর্ণ।
a = [1, "200", 1.3]
a.slice_before(String).to_a # => [[1], ["200", 1.3]]
ব্লক ব্যবহার
যদি অন্য কোনো অপশন আপনার জন্য পর্যাপ্ত ফ্লেক্সিবল না হয়, তবে আপনি প্রোগ্রাম্যাটিক্যালি একটি ব্লক দিয়ে ম্যাচ খুঁজে বের করতে পারেন।
a = [1, 2, 3, 4, 5]
a.slice_before do |item|
item % 2 == 0
end
# => [[1], [2, 3], [4, 5]]
Enumerable#slice_after ব্যবহার
Enumerable#slice_after Enumerable#slice_before-এর মতোই কাজ করে সिवায় স্লাইস হয় ম্যাচের পরে। যেন। :-)
a = ["a", "b", "c"]
a.slice_after("b").to_a # => [["a", "b"], ["c"]]
অবশ্যই, আপনি রেগুলার এক্সপ্রেশন, রেঞ্জ, এবং ব্লক দিয়ে ম্যাচ করতে পারেন। আমি এখানে সেগুলোর উদাহরণ দেখাচ্ছি না কারণ এটি repetitive হত।
Enumerable#slice_when ব্যবহার
Enumerable#slice_when slice_before এবং slice_after- থেকে আলাদা একটি জিনিস। এনumerable-এর একটি একক আইটেম ম্যাচ করার বদলে, আপনি দুটি সংলগ্ন আইটেমের জোড়া ম্যাচ করেন।
এর মানে আপনি আইটেমগুলো তাদের মাঝপথের "এজ"-এর ভিত্তিতে গ্রুপ করতে পারেন।
উদাহরণস্বরূপ, এখানে আমরা আইটেমগুলো তাদের সংলগ্ন আইটেমের সাথে "নিকটতা"র ভিত্তিতে গ্রুপ করছি।
a = [1, 2, 3, 100, 101, 102]
# দুটি সংলগ্ন আইটেমের পার্থক্য ১০-এর চেয়ে বেশি হলে নতুন গ্রুপ তৈরি করুন
a.slice_when do |x, y|
(y - x) > 10
end
# => [[1, 2, 3], [100, 101, 102]]
আপনি যদি আরও জানতে চান, রুবি ডক্সের slice_when দেখুন। সেখানে অনেক চমৎকার কোড উদাহরণ আছে।
অ্যারে বনাম এনumerable
আমি উপরের অধিকাংশ উদাহরণে অ্যারে ব্যবহার করেছি কারণ অ্যারে বুঝতে সহজ। কিন্তু খেয়াল রাখুন, আপনি slice_before, slice_when এবং slice_after যেকোনো এনumerable-এর সাথে ব্যবহার করতে পারেন।
উদাহরণস্বরূপ, আপনার কাছে একটি ফাইল আছে যেটিতে অনেক ইমেইল আছে, তবে আপনি slice_before ব্যবহার করে প্রতিটি ইমেইল আলাদা করতে পারেন। নিচের কোড ডক্স থেকে নেওয়া।
open("mbox") { |f|
f.slice_before { |line| line.start_with? "From " }.each { |mail| puts mail }
}
এবং লক্ষ্য করুন যে স্লাইস মেথডগুলো অ্যারে রিটার্ন করে না। সেগুলো এনumerable রিটার্ন করে। অর্থাৎ আপনি সেগুলোর ওপর map, each এবং আপনার সব প্রিয় এনumerable মেথড ব্যবহার করতে পারেন। হেক, আপনি আবার স্লাইসও করতে পারেন। :)