অ্যারে একটি মিউটেবল ডেটা স্ট্রাকচার, যা একটি নির্দিষ্ট টাইপের এলিমেন্টের সংগ্রহ সংরক্ষণ করে। অ্যারে একটি ইনডেক্সেবল ডেটা স্ট্রাকচার। অ্যারে মিউটেবল হওয়ার অর্থ হলো, যদি কোনো অ্যারের উপর এমন একটি মেথড কল করা হয় যা অ্যারেটি পরিবর্তন করে, তাহলে অ্যারেটি পরিবর্তিত হবে। অর্থাৎ এটি নতুন কোনো অ্যারে তৈরি করে না, বরং বিদ্যমান অ্যারেটিই পরিবর্তন করে।
একটি অ্যারে তৈরি করতে অ্যারে লিটারেল লেখার সিনট্যাক্স ([]) ব্যবহার করুন এবং তার ভেতরে কমা দিয়ে আলাদা করে অ্যারের এলিমেন্টগুলো উল্লেখ করুন।
[1, 2, 3] # => [1, 2, 3]
Crystal এলিমেন্টগুলো থেকে অ্যারের টাইপ অনুমান করবে।
[1, 2, 3].class # => Array(Int32)
আগে বলা হয়েছে যে অ্যারে একটি নির্দিষ্ট টাইপের এলিমেন্টের সংগ্রহ, তবুও ইউনিয়ন টাইপ ব্যবহার করে আপনি একাধিক টাইপের একটি অ্যারে তৈরি করতে পারেন। এতে অ্যারে ইউনিয়ন টাইপে উল্লেখিত যেকোনো টাইপের এলিমেন্ট ধারণ করতে পারে। Crystal এলিমেন্টগুলো থেকে অ্যারের টাইপ অনুমান করবে।
[1, "2", 3.0] # => [1, "2", 3.0]
[1, "2", 3.0].class # => Array(Int32 | Float64 | String)
একটি বহুমাত্রিক অ্যারে হলো অ্যারেগুলোর একটি অ্যারে।
এর অর্থ হলো অ্যারের প্রতিটি এলিমেন্ট নিজেই একটি অ্যারে।
টেবিল আকারে ডেটা সংরক্ষণ করতে চাইলে এটি কাজে লাগতে পারে।
একটি বহুমাত্রিক অ্যারে ডিফাইন করতে আপনি হয় অ্যারে-এর অ্যারে লিটারেল লিখতে পারেন, নয়তো Array.new কনস্ট্রাক্টর ব্যবহার করতে পারেন।
[[1, 2], [3, 4]] # => [[1, 2], [3, 4]]
numbers = Array(Array(Int32)).new() # => []
numbers << [1, 2] # => [[1, 2]]
অ্যারেতে একটি এলিমেন্ট যোগ করতে << (অ্যাপেন্ড) অপারেটর ব্যবহার করুন।
[1, 2, 3] << 4 # => [1, 2, 3, 4]
আপনি যে এলিমেন্টটি যোগ করতে চান তার টাইপ অ্যারের টাইপের সঙ্গে একই হতে হবে, না হলে একটি এরর উত্থাপিত হবে।
numbers : Array(Int32 | Float64) = [1, 2, 3]
numbers << 4.0
numbers # => [1, 2, 3, 4.0]
numbers << "5" # => Error: no overload matches 'Array(Int32 | Float64)#<<' with type String
String-এর মতোই, size মেথড ব্যবহার করে আপনি একটি অ্যারের আকার পেতে পারেন।
[1, 2, 3].size # => 3
খালি অ্যারে তৈরি করার সময় কম্পাইলার অ্যারের টাইপ অনুমান করতে পারে না।
তাই আপনাকে অ্যারের টাইপ উল্লেখ করতে হবে।
এটি করা যায় অ্যারের টাইপ উল্লেখ করে, of কিওয়ার্ড ব্যবহার করে, অথবা অ্যারে ইনিশিয়ালাইজার সিনট্যাক্স ব্যবহার করে, যা হলো Array(T).new।
[] of (Int32 | Float64 | String) # => []
Array(Int32 | Float64 | String).new # => []
String-এর মতোই, [] (ইনডেক্স) অপারেটর ব্যবহার করে এবং যে এলিমেন্টটি অ্যাক্সেস করতে চান তার ইনডেক্স দিয়ে আপনি অ্যারের এলিমেন্টগুলো অ্যাক্সেস করতে পারেন।
ইনডেক্স সীমার বাইরে গেলে একটি IndexError উত্থাপিত হবে।
[1, 2, 3][0] # => 1
[1, 2, 3][3] # => Index out of bounds (IndexError)
রেঞ্জ ব্যবহার করেও এলিমেন্ট অ্যাক্সেস করা সম্ভব।
[1, 2, 3][0..1] # => [1, 2]
রেঞ্জ থেকে একটি অ্যারে তৈরি করতে to_a মেথড ব্যবহার করুন।
সংখ্যার একটি অ্যারে তৈরি করতে চাইলে এটি কাজে লাগতে পারে।
(1..3).to_a # => [1, 2, 3]
স্ট্রিং থেকে একটি অ্যারে তৈরি করতে split মেথড ব্যবহার করুন।
এটি দিয়ে একটি ডেলিমিটার ব্যবহার করে একটি স্ট্রিংকে স্ট্রিংয়ের অ্যারেতে ভাগ করা যায়।
"1,2,3".split(",") # => ["1", "2", "3"]
chars মেথড ব্যবহার করে একটি স্ট্রিং থেকে ক্যারেক্টারের অ্যারে পাওয়াও সম্ভব।
"123".chars # => ['1', '2', '3']
Char বা String-এর একটি অ্যারে String-এ রূপান্তর করতে আপনি join মেথড ব্যবহার করতে পারেন, যা আর্গুমেন্ট হিসেবে একটি ডেলিমিটার নেয়।
['1', '2', '3'].join(".") # => "1.2.3"
অ্যারের শেষ থেকে একটি এলিমেন্ট মুছে ফেলতে চাইলে আপনি pop মেথড ব্যবহার করতে পারেন, যা ঐচ্ছিক একটি আর্গুমেন্ট নেয়, যেখানে উল্লেখ থাকে অ্যারের শেষ থেকে কতগুলো এলিমেন্ট সরাতে হবে।
মেথডটি সরিয়ে ফেলা এলিমেন্টটি রিটার্ন করে।
অ্যারেটি খালি থাকলে একটি IndexError উত্থাপিত হবে।
numbers = [1, 2, 3]
numbers.pop # => 3
numbers # => [1, 2]
empty_numbers = [] of Int32
empty_numbers.pop # => Index out of bounds (IndexError)
অ্যারে থেকে নির্দিষ্ট ইনডেক্সের একটি এলিমেন্ট মুছে ফেলতে চাইলে আপনি delete_at মেথড ব্যবহার করতে পারেন, যা আর্গুমেন্ট হিসেবে সরিয়ে ফেলার জন্য এলিমেন্টটির ইনডেক্স নেয়।
অ্যারেটি খালি থাকলে একটি IndexError উত্থাপিত হবে।
numbers = [1, 2, 3]
numbers.delete_at(1) # => 2
numbers # => [1, 3]
empty_numbers = [] of Int32
empty_numbers.delete_at(0) # => Index out of bounds (IndexError)
অ্যারে থেকে নির্দিষ্ট ইনডেক্সের একটি এলিমেন্ট পরিবর্তন করতে চাইলে আপনি []= (ইনডেক্স অ্যাসাইন) অপারেটর ব্যবহার করতে পারেন, যা আর্গুমেন্ট হিসেবে পরিবর্তন করার জন্য এলিমেন্টটির ইনডেক্স এবং নতুন মান নেয়।
ইনডেক্স সীমার বাইরে গেলে একটি IndexError উত্থাপিত হবে।
numbers = [1, 2, 3]
numbers[1] = 4
numbers # => [1, 4, 3]
numbers[3] = 5 # => Index out of bounds (IndexError)
এই অনুশীলনীতে প্রোগ্রামিং ভাষার একটি অ্যারে নিয়ে কাজ করার জন্য আপনাকে কিছু মেথড ইমপ্লিমেন্ট করতে হবে।
LanguageList.list মেথডটি ডিফাইন করুন, যেটি কোনো আর্গুমেন্ট নেয় না এবং Array(String) টাইপের একটি খালি অ্যারে রিটার্ন করে।
LanguageList.list()
# => []
LanguageList.add মেথডটি ডিফাইন করুন, যেটি ২টি আর্গুমেন্ট নেয় (একটি ভাষার অ্যারে এবং একটি ভাষার স্ট্রিং লিটারাল)। মেথডটি অ্যারের শেষে নতুন ভাষাটি যোগ করে সেই অ্যারেটি রিটার্ন করবে।
language_list = LanguageList.list()
# => []
language_list = LanguageList.add(language_list, "Crystal")
# => ["Crystal"]
language_list = LanguageList.add(language_list, "Ruby")
# => ["Crystal", "Ruby"]
LanguageList.remove মেথডটি ডিফাইন করুন, যেটি ১টি আর্গুমেন্ট নেয় (একটি ভাষার অ্যারে)। মেথডটি শেষ এলিমেন্টটি ছাড়া অ্যারেটি রিটার্ন করবে। ধরে নিন যে অ্যারেতে সবসময় অন্তত একটি এলিমেন্ট থাকবে।
language_list = LanguageList.list()
# => []
language_list = LanguageList.add(language_list, "Crystal")
# => ["Crystal"]
language_list = LanguageList.add(language_list, "Ruby")
# => ["Crystal", "Ruby"]
language_list = LanguageList.remove(language_list)
# => ["Crystal"]
LanguageList.at ফাংশনটি ডিফাইন করুন, যেটি ২টি আর্গুমেন্ট নেয় (একটি ভাষার অ্যারে এবং একটি ইনডেক্স)। মেথডটি অ্যারেতে n ইনডেক্সে থাকা ভাষাটি রিটার্ন করবে। ধরে নিন যে ওই ইনডেক্সে সবসময় একটি ভাষা থাকবে।
language_list = LanguageList.new()
# => []
language_list = LanguageList.add(language_list, "Crystal")
# => ["Crystal"]
language_list = LanguageList.add(language_list, "Ruby")
# => ["Crystal", "Ruby"]
LanguageList.at(language_list, 1)
# => "Ruby"
LanguageList.parse মেথডটি ডিফাইন করুন, যেটি ১টি আর্গুমেন্ট নেয় (কমা দিয়ে আলাদা করা ভাষাগুলোর একটি স্ট্রিং লিটারাল)। মেথডটি ভাষাগুলোর একটি অ্যারে রিটার্ন করবে।
LanguageList.parse("Crystal, Ruby")
# => ["Crystal", "Ruby"]
Exercism-এ সাইন আপ করুন, Crystal ট্র্যাকের 26টি কনসেপ্ট142টি অনুশীলনী আর সত্যিকারের মানুষের মেন্টরিং দিয়ে শিখুন ও দক্ষ হয়ে উঠুন, সম্পূর্ণ বিনামূল্যে।