Tuple অনেক দিক থেকেই Vector (একমাত্রিক array)-এর সঙ্গে bastante মিল রাখে। তবে কয়েকটি গুরুত্বপূর্ণ পার্থক্যও আছে।
[ ]-এর বদলে প্রথম বন্ধনী ( ) দিয়ে, যদিও অর্থ স্পষ্ট থাকলে বন্ধনীগুলো বাদ দেওয়া যায়।ইমিউটেবিলিটির কারণে কম্পাইলার আরও অপটিমাইজেশন করতে পারে এবং টুপল ভেক্টরের চেয়ে বেশি পারফরম্যান্ট হয়, তাই যেখানে মিউটেবিলিটির প্রয়োজন নেই সেখানে টুপল ব্যবহার করাই ভালো।
julia> t = (3, 5.2, "xyz")
(3, 5.2, "xyz")
# Non-homogeneous:
julia> dump(t)
Tuple{Int64, Float64, String}
1: Int64 3
2: Float64 5.2
3: String "xyz"
julia> t[2]
5.2
# Immutable:
julia> t[2] = 7.3
ERROR: MethodError: no method matching setindex!(::Tuple{Int64, Float64, String})
এছাড়া Tuple() নামের একটি কনস্ট্রাক্টরও আছে, যা যেকোনো ইটারেবল কালেকশনকে একটি টুপলে পরিণত করে। সুবিধার কথা হলো, এটি একটি স্ট্রিংকে ক্যারেক্টারের ইটারেবল কালেকশন হিসেবে বিবেচনা করে।
julia> Tuple("Julia")
('J', 'u', 'l', 'i', 'a')
যেকোনো টুপলের ক্ষেত্রেই ইনডেক্স দিয়ে এলিমেন্ট অ্যাক্সেস করা বা সেগুলোর উপর লুপ চালানো সম্ভব।
শুধু সংখ্যা দিয়ে গঠিত যেকোনো টুপল অ্যারেগুলোর মতোই sum()-এর মতো গাণিতিক ফাংশনে ব্যবহার করা যায়।
একাধিক অ্যাসাইনমেন্ট ব্যবহার করে একটি টুপলকে আলাদা আলাদা এলিমেন্টে আনপ্যাক করা যায়।
যে এলিমেন্টগুলো দরকার নেই সেগুলোর জন্য ডামি ভ্যারিয়েবল হিসেবে আন্ডারস্কোর _ ব্যবহার করুন।
julia> tup = (1, "Julia", true)
(1, "Julia", true)
julia> num, name, _ = tup
(1, "Julia", true)
julia> uppercase(name), 2num
("JULIA", 2)
Python প্রোগ্রামারদের কাছে এই একাধিক-অ্যাসাইনমেন্ট সিনট্যাক্স বেশ পরিচিতই।
একটি Tuple-এ শুধু ভ্যালু থাকে।
NamedTuple প্রতিটি ভ্যালুর সঙ্গে একটি নাম জুড়ে দেয়।
এরপর "ডট" নোটেশন দিয়ে প্রতিটি ফিল্ড অ্যাক্সেস করা যায়:
julia> nt = (a = 1, b = 7.3)
(a = 1, b = 7.3)
julia> dump(nt)
@NamedTuple{a::Int64, b::Float64}
a: Int64 1
b: Float64 7.3
julia> nt.b
7.3
নামটি অভ্যন্তরীণভাবে Symbol (একটি ইমিউটেবল টাইপ, যার শুরুতে কোলন : থাকে) হিসেবে সংরক্ষিত হয়, তাই একটি বিকল্প সিনট্যাক্সও পাওয়া যায়:
julia> nt[:b]
7.3
নামগুলো (যাদের কী (key)-ও বলা হয়) কিংবা শুধু ভ্যালুগুলো আলাদাভাবেও সহজেই পাওয়া যায়:
julia> nt
(a = 1, b = 7.3)
julia> keys(nt)
(:a, :b)
julia> values(nt)
(1, 7.3)
মনে রাখবেন, একটি নেমড টুপলের উপর ইটারেশন করলে শুধু ভ্যালুগুলোই পাওয়া যায়, আর নামগুলো উপেক্ষিত থাকে।
টুপল (নেমড হোক বা না হোক) ফাংশনে ও ফাংশন থেকে স্ট্রাকচার্ড ডেটা পাঠানোর খুব কমন একটি উপায়। এই কাজে ইমিউটেবিলিটি ভালো, কারণ এটি ডেটার নিরাপত্তা দেয় এবং কম্পাইলারকে আরও জোরালো অপটিমাইজেশনের সুযোগ করে দেয়।
আজারা আর রুই একই দলের সাথী, তারা জলদস্যু থিমের একটি গুপ্তধন অনুসন্ধানে প্রতিযোগিতা করছে। একজনের কাছে মানচিত্রের স্থানাঙ্কসহ গুপ্তধনের একটি তালিকা আছে, আর অন্যজনের কাছে মানচিত্রের স্থানাঙ্কসহ স্থানের নামের একটি তালিকা। তাদের ফাঁকা মানচিত্রও দেওয়া হয়েছে, যেখানে শুরুর জায়গাটি "আপনি এখানে আছেন" বলে চিহ্নিত করা আছে।
| আজারার তালিকা | রুইয়ের তালিকা | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
কিন্তু সবকিছু একটু এলোমেলো: আজারার স্থানাঙ্কগুলো রুইয়ের থেকে আলাদা ভাবে লেখা আর আলাদা ক্রমে সাজানো মনে হচ্ছে, আর কোন গুপ্তধন কোন স্থানের সাথে মেলে সেটা বের করতে তাদের এক তালিকা থেকে আরেক তালিকায় বারবার চোখ বুলাতে হচ্ছে। তারা দুজনেই নতুন নতুন Julia প্রোগ্রামার, তাই নিজেদের অনুসন্ধানের তথ্য আরও ভালোভাবে গুছিয়ে রাখার জন্য একটি ছোট প্রোগ্রাম (আসলে কয়েকটি ফাংশনের একটি সেট) লিখতে তারা আপনার কাছে সাহায্য নিতে এসেছে।
এমন একটি get_cooordinate() ফাংশন বাস্তবায়ন করুন, যা আজারার তালিকা থেকে একটি (treasure, coordinate) জোড়া নেয় এবং শুধু বের করা মানচিত্রের স্থানাঙ্কটি রিটার্ন করে।
julia> get_cooordinate( ("Scrimshaw Whale's Tooth", "2A") )
"2A"
এমন একটি convert_coordinate() ফাংশন বাস্তবায়ন করুন, যা "2A" ফরম্যাটের একটি স্থানাঙ্ক নেয় এবং ('2', 'A') ফরম্যাটের একটি টুপল রিটার্ন করে।
julia> convert_coordinate("2A")
('2', 'A')
এমন একটি compare_records() ফাংশন বাস্তবায়ন করুন, যা একটি (treasure, coordinate) জোড়া এবং একটি (location, coordinate, quadrant) রেকর্ড নেয় এবং দুটির স্থানাঙ্ক তুলনা করে।
স্থানাঙ্কগুলো "মিলে গেলে" true রিটার্ন করুন, আর না মিললে false রিটার্ন করুন।
সঠিকভাবে তুলনা করার জন্য প্রয়োজন অনুযায়ী স্থানাঙ্কগুলো আবার ফরম্যাট করে নিন।
julia> compare_records(("Brass Spyglass", "4B"), ("Seaside Cottages", ('1', 'C'), "blue"))
false
julia> compare_records(("Model Ship in Large Bottle", "8A"), ("Harbor Managers Office", ('8', 'A'), "purple"))
true
এমন একটি create_record() ফাংশন বাস্তবায়ন করুন, যা আজারার তালিকা থেকে একটি (treasure, coordinate) জোড়া এবং রুইয়ের তালিকা থেকে একটি (location, coordinate, quadrant) রেকর্ড নেয়, আর স্থানাঙ্কগুলো মিলে গেলে (coordinate, location, quadrant, treasure) রিটার্ন করে।
স্থানাঙ্কগুলো যদি না মেলে, তাহলে একটি খালি টুপল রিটার্ন করুন। সঠিকভাবে তুলনা করার জন্য প্রয়োজন অনুযায়ী স্থানাঙ্কগুলো আবার ফরম্যাট করে নিন।
julia> create_record(("Brass Spyglass", "4B"), ("Abandoned Lighthouse", ('4', 'B'), "Blue"))
("4B", "Abandoned Lighthouse", "Blue", "Brass Spyglass")
julia> create_record(("Brass Spyglass", "4B"), ("Seaside Cottages", ('1', 'C'), "Blue"))
()
Exercism-এ সাইন আপ করুন, Julia ট্র্যাকের 35টি কনসেপ্ট128টি অনুশীলনী আর সত্যিকারের মানুষের মেন্টরিং দিয়ে শিখুন ও দক্ষ হয়ে উঠুন, সম্পূর্ণ বিনামূল্যে।