জুলিয়ার একটি মূল লক্ষ্য হলো সংখ্যাগত ডেটার উপর দ্রুত ও দক্ষভাবে হিসাব করতে পারা। প্রচুর সংখ্যাগত ডেটা।
সাধারণত ডেটা অ্যারেতে (বা সম্পর্কিত কোনো টাইপে) সংরক্ষণ করা হয়, তাই এটা বলা যায় যে অ্যারেগুলো জুলিয়া ভাষার একেবারে কেন্দ্রে রয়েছে।
অ্যারে যত বড় খুশি হতে পারে (একমাত্র সীমা হলো আপনার হার্ডওয়্যারের মেমোরি), আর এর ডাইমেনশনও যত খুশি হতে পারে।
এই পরিচিতিমূলক কনসেপ্টে মূলত এক-মাত্রিক অ্যারের মূল বিষয়গুলো নিয়ে আলোচনা করা হয়েছে, যাদের ভেক্টর বলা হয়।
জুলিয়ায় একটি ভেক্টর হলো মানের একটি সাজানো ক্রম, যার প্রতিটি মান ইনডেক্স নম্বর দিয়ে অ্যাক্সেস করা যায়।
ভেক্টর তৈরির সবচেয়ে সহজ উপায় হলো মানগুলো তৃতীয় বন্ধনীর মধ্যে তালিকা করে লেখা:
julia> num_vec = [1, 4, 9]
3-element Vector{Int64}:
1
4
9
julia> str_vec = ["arrays", "are", "important"]
3-element Vector{String}:
"arrays"
"are"
"important"
ভেক্টরের টাইপ প্রতিটি এলিমেন্টের টাইপের সাথে মেলে।
তাহলে ভেক্টরগুলোকে হোমোজিনিয়াস হতে হবে (সব এলিমেন্ট একই টাইপের)?
কোনো এক অর্থে হ্যাঁ, আর আপনি যদি সেরা পারফরম্যান্স চান, তবে এটাই লক্ষ্য রাখার পরামর্শ দেওয়া হয়।
তবে জুলিয়া প্রয়োজনে এই সীমাবদ্ধতা এড়িয়ে যেতে পারে Any টাইপ ব্যবহার করে:
julia> mixed_vector = [1, "str", 'c']
3-element Vector{Any}:
1
"str"
'c': ASCII/Unicode U+0063 (category Ll: Letter, lowercase)
খালি ভেক্টর তৈরি করার সময় জুলিয়া ডিফল্টভাবে এলিমেন্ট টাইপ হিসেবে Any নেয়, তবে পছন্দের এলিমেন্ট টাইপ দিয়ে খালি অ্যারেটি অ্যানোটেট করে এটিকে আরও নির্দিষ্টভাবে ঠিক করা যায়।
julia> empty_vec = []
Any[]
julia> empty_int_vec = Int64[]
Int64[]
অনুগ্রহ করে এই নিয়মটি পড়ুন এবং মনে রাখুন:
যারা অন্য ডেটা সায়েন্স ভাষা (R, Matlab, Fortran...) ব্যবহার করেছেন তাদের কাছে এটি চেনা, তবে C-এর মতো ভাষার পটভূমি আছে এমন কম্পিউটার সায়েন্টিস্টদের কাছে এটি হতবাক করার মতো লাগতে পারে।
এছাড়া ইনডেক্স কাজ করে ঠিক যেভাবে আপনি ভাবতে পারেন: শুধু এগুলো তৃতীয় বন্ধনীর মধ্যে বসান:
squares = [0, 1, 4, 9, 16]
squares[1] # 0
squares[3] # 4
squares[begin] # 0 ("begin" is synonym for 1)
squares[end] # 16 ("end" is synonym for length(squares))
লক্ষ্য করুন end দিয়ে ইনডেক্স করা কত সুবিধাজনক (যা খুবই কাজের) আর begin দিয়ে (যা সম্ভবত নয়)।
পাইথন প্রোগ্রামাররা হয়তো ঋণাত্মক ইনডেক্স নিয়ে ভাবছেন।
ভাববেন না: এগুলো জুলিয়ার অংশ নয়, আর এগুলো ব্যবহার করলে একটি BoundsError তৈরি হয়, ঠিক যেভাবে 1-এর চেয়ে ছোট বা length(squares)-এর চেয়ে বড় যেকোনো ইনডেক্স করলে হয়।
জুলিয়ায় ভেক্টরগুলো মিউটেবল: আমরা আলাদা আলাদা সেলের ভেতরের মান বদলে দিতে পারি।
julia> vals = [1, 3, 5, 7]
4-element Vector{Int64}:
1
3
5
7
julia> vals[2] = 4 # reassign the value of this element
4
# Only the value at position 2 changes:
julia> vals
4-element Vector{Int64}:
1
4
5
7
ভেক্টর নিয়ে কাজ করার জন্য অনেক ফাংশন আছে, যদিও জুলিয়ার ডকুমেন্টেশনে এগুলোকে ভেক্টরের বদলে আরও সাধারণভাবে "কালেকশন" বলা হয়।
লক্ষ্য করুন, কনভেনশন অনুযায়ী যে ফাংশনগুলো নিজের ইনপুট মিউটেট করে তাদের নামে ! থাকে।
কম্পাইলার এটি বাধ্যতামূলক করে না, তবে জুলিয়ার জগতে এটি একটি খুবই জোরালো কনভেনশন।
এখানে এমন কয়েকটি কাজের ফাংশন দেওয়া হলো:
push!() ব্যবহার করুন।pop!() ব্যবহার করুন।pushfirst!() আর popfirst!()।insert!() আর deleteat!()।julia> vals = [1, 3]
2-element Vector{Int64}:
1
3
julia> push!(vals, 5, 6) # can add multiple values
4-element Vector{Int64}:
1
3
5
6
julia> pop!(vals) # mutates vals, return popped value
6
julia> vals
3-element Vector{Int64}:
1
3
5
ভবিষ্যতের এক জাদুকর হিসেবে Elyse-কে কিছু মৌলিক বিষয় অনুশীলন করতে হবে। তার কাছে কার্ডের একটি স্ট্যাক আছে, যেটি নিয়ে সে নানা রকম কারিকুরি করতে চায়।
কাজটি একটু সহজ করতে সে শুধু ১ থেকে ১০ নম্বরের কার্ডগুলোই ব্যবহার করে, তাই তার কার্ডের স্ট্যাককে সংখ্যার একটি ভেক্টর দিয়ে প্রকাশ করা যায়। কোনো নির্দিষ্ট কার্ডের অবস্থান ভেক্টরের ইনডেক্সের সাথে মিলে যায়।
একটি কার্ড নিতে হলে প্রদত্ত স্ট্যাক থেকে position ইনডেক্সের কার্ডটি রিটার্ন করুন।
julia> stack = [1, 2, 4, 1];
julia> position = 3;
julia> get_item(stack, position)
4
একটু হাতের কৌশল দেখিয়ে position ইনডেক্সের কার্ডটি প্রদত্ত রিপ্লেসমেন্ট কার্ডের সাথে বদলে দিন।
পরিবর্তিত স্ট্যাকটি রিটার্ন করুন।
julia> stack = [1, 2, 4, 1];
julia> position = 3;
julia> replacement_card = 6;
julia> set_item!(stack, position, replacement_card)
[1, 2, 6, 1]
স্ট্যাকের একেবারে উপরে একটি নতুন কার্ড ঢুকিয়ে একটি কার্ড হাজির করুন। পরিবর্তিত স্ট্যাকটি রিটার্ন করুন।
julia> stack = [5, 9, 7, 1];
julia> new_card = 8;
julia> insert_item_at_top!(stack, new_card)
[5, 9, 7, 1, 8]
স্ট্যাক থেকে প্রদত্ত position ইনডেক্সের কার্ডটি সরিয়ে একটি কার্ড গায়েব করুন।
পরিবর্তিত স্ট্যাকটি রিটার্ন করুন।
julia> stack = [3, 2, 6, 4, 8];
julia> position = 3;
julia> remove_item!(stack, position)
[3, 2, 4, 8]
স্ট্যাকের উপরের কার্ডটি সরিয়ে একটি কার্ড গায়েব করুন। পরিবর্তিত স্ট্যাকটি রিটার্ন করুন।
julia> stack = [3, 2, 6, 4, 8];
julia> remove_item_from_top!(stack)
[3, 2, 6, 4]
স্ট্যাকের একেবারে নিচে একটি নতুন কার্ড ঢুকিয়ে একটি কার্ড হাজির করুন। পরিবর্তিত স্ট্যাকটি রিটার্ন করুন।
julia> stack = [5, 9, 7, 1];
julia> new_card = 8;
julia> insert_item_at_bottom!(stack, new_card)
[8, 5, 9, 7, 1]
স্ট্যাকের একেবারে নিচের কার্ডটি সরিয়ে একটি কার্ড গায়েব করুন। পরিবর্তিত স্ট্যাকটি রিটার্ন করুন।
julia> stack = [8, 5, 9, 7, 1];
julia> remove_item_at_bottom!(stack)
[5, 9, 7, 1]
স্ট্যাকের আকার stack_size-এর সমান কি না, তা যাচাই করুন।
julia> stack = [3, 2, 6, 4, 8];
julia> stack_size = 4;
julia> check_size_of_stack(stack, stack_size)
false
Exercism-এ সাইন আপ করুন, Julia ট্র্যাকের 35টি কনসেপ্ট128টি অনুশীলনী আর সত্যিকারের মানুষের মেন্টরিং দিয়ে শিখুন ও দক্ষ হয়ে উঠুন, সম্পূর্ণ বিনামূল্যে।