Ruby-এর each_cons মেথড
Ruby-এ `each_cons(n)` একটি এনামারেবল মেথড যা প্রতিটি এলিমেন্ট থেকে শুরু করে `n` সংখ্যক সংলগ্ন (consecutive) এলিমেন্ট নিয়ে সাব-অ্যারে বানায়।
# Ruby
[1,2,3,4,5].each_cons(2).to_a
# => [[1,2], [2,3], [3,4], [4,5]]
JavaScript-এ ইমপ্লিমেন্টেশন (স্লাইডিং উইন্ডো)
const eachCons = function(num) {
let res = [], temp = [];
let start = 0, end = 0;
// ইনিশিয়াল উইন্ডো বানান
while (end < num) {
temp.push(this[end++]);
}
// স্লাইড করুন
for (; end <= this.length; ) {
if (temp.length === num) {
res.push([...temp]); // কপি পুশ করুন (রেফারেন্স না)
start++;
end = start;
temp = [];
}
temp[end - start] = this[end];
end++;
}
return res;
};
Array.prototype.eachCons = eachCons;
console.log([1,2,3,4,5].eachCons(1)); // [[1],[2],[3],[4],[5]]
console.log([1,2,3,4,5].eachCons(2)); // [[1,2],[2,3],[3,4],[4,5]]
console.log([1,2,3,4,5].eachCons(3)); // [[1,2,3],[2,3,4],[3,4,5]]
console.log([1,2,3,4,5].eachCons(4)); // [[1,2,3,4],[2,3,4,5]]
আউটপুট
[ [ 1 ], [ 2 ], [ 3 ], [ 4 ], [ 5 ] ]
[ [ 1, 2 ], [ 2, 3 ], [ 3, 4 ], [ 4, 5 ] ]
[ [ 1, 2, 3 ], [ 2, 3, 4 ], [ 3, 4, 5 ] ]
[ [ 1, 2, 3, 4 ], [ 2, 3, 4, 5 ] ]
কোড ব্যাখ্যা
- প্রোটোটাইপ এক্সটেনশন: `Array.prototype.eachCons = ...` - সব অ্যারেয়ে মেথড যোগ
- স্লাইডিং উইন্ডো: `start` এবং `end` পয়েন্টার দিয়ে উইন্ডো ম্যানেজ
- ইনিশিয়ালাইজেশন: প্রথমে `num` সংখ্যক এলিমেন্ট উইন্ডোতে নেওয়া
- স্লাইড: উইন্ডো ফুল হলে রেজাল্টে পুশ, উইন্ডো রিসেট, আবার বানান
⚠️ প্রোটোটাইপ পলিউশন সতর্কতা
বিল্ট-ইন প্রোটোটাইপ এক্সটেন্ড করা **অনुशंसিত নয়** (नाम конфлиক্ট, লাইব্রেরি কনফ্লিক্ট)। বরং স্ট্যান্ডঅ্যালোন ফাংশন বা Static মেথড ব্যবহার করুন।
আধুনিক ও সুরক্ষিত ইমপ্লিমেন্টেশন
১. স্ট্যান্ডঅ্যালোন ফাংশন (প্রস্তাবিত)
const eachCons = (arr, n) => {
if (n <= 0 || n > arr.length) return [];
const result = [];
for (let i = 0; i <= arr.length - n; i++) {
result.push(arr.slice(i, i + n));
}
return result;
};
// ব্যবহার
console.log(eachCons([1,2,3,4,5], 2)); // [[1,2],[2,3],[3,4],[4,5]]
২. Generator (মেমরি দক্ষ - Lazy Evaluation)
function* eachConsGen(arr, n) {
if (n <= 0 || n > arr.length) return;
for (let i = 0; i <= arr.length - n; i++) {
yield arr.slice(i, i + n);
}
}
// ব্যবহার
for (const window of eachConsGen([1,2,3,4,5], 3)) {
console.log(window); // একবারে একটা প্রসেস
}
// অথবা অ্যারেতে কনভার্ট
const result = [...eachConsGen([1,2,3,4,5], 2)];
৩. Static Array মেথড (Array.eachCons = ...)
Array.eachCons = (arr, n) => {
if (!Array.isArray(arr) || n <= 0 || n > arr.length) return [];
return Array.from({ length: arr.length - n + 1 }, (_, i) => arr.slice(i, i + n));
};
পারফরম্যান্স তুলনা
| পদ্ধতি | টাইম | স্পেস | লেজি |
|---|---|---|---|
| Slice in Loop | O(n×k) | O(n×k) | না |
| Generator | O(n×k) | O(k) | হ্যাঁ |
| Array.from + slice | O(n×k) | O(n×k) | না |
নোট: `slice` O(k), তাই মোট O(n×k)। কনস্ট্যান্ট k হলে O(n)।
ব্যবহারিক অ্যাপ্লিকেশন
- টাইম সিরিজ অ্যানালাইসিস: রোলিং উইন্ডো ক্যালকুলেশন
- NLP: n-gram জেনারেশন (বিগ্রাম, ট্রিগ্রাম)
- সিগন্যাল প্রসেসিং: মুভিং অ্যভারেজ, ফিল্টার
- ফিনান্স: টেকনিক্যাল ইন্ডিকেটর (RSI, MACD)
সারাংশ
Ruby-এর `each_cons` সমতুল্য JS-এ সহজে ইমপ্লিমেন্ট করা যায়। প্রোটোটাইপ পলিউশন এড়াতে স্ট্যান্ডঅ্যালোন ফাংশন বা `Array.eachCons` static মেথড ব্যবহার করুন। বড় ডেটার জন্য জেনারেটর (lazy) সেরা।