কম্পিউটার টিউটোরিয়াল

JavaScript-এ Ruby-এর each_cons সমতুল্য ইমপ্লিমেন্টেশন

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 LoopO(n×k)O(n×k)না
GeneratorO(n×k)O(k)হ্যাঁ
Array.from + sliceO(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) সেরা।

  1. জাভাস্ক্রিপ্টে প্রতিটি অবজেক্টের জন্য ইউনিক আইডি তৈরি করা

  2. জাভাস্ক্রিপ্টে অ্যারে-এর প্রতিটি এলিমেন্টে f(x) প্রয়োগ করা

  3. জাভাস্ক্রিপ্টে লিংকড লিস্টে প্রতিটি নোডের জন্য পরবর্তী বড় মান খুঁজে বের করা

  4. রুবির Enumerable মডিউল শিখুন: পাওয়ারফুল কলেকশন মেথড আনলক করুন