R-এ একটি list হলো ক্রমানুসারে সাজানো আইটেমের একটি সংগ্রহ, যা কয়েকটি দিক থেকে vectors-এর চেয়ে আলাদা:
numeric-এর সাথে character মেশানো)।অন্য ভাষার সাথে এর তুলনা একেবারে নির্ভুল নয়।
R-এর একটি list কিছুটা Python-এর ডিকশনারির মতো, তবে list ক্রমানুসারে সাজানো থাকে এবং সংখ্যাগত ইনডেক্স দিয়ে অ্যাক্সেস করা যায়।
এটি C-এর একটি struct-এর সঙ্গেও কিছুটা মেলে, তবে পার্থক্য হলো list রানটাইমে সহজেই সম্প্রসারিত করা যায়।
এলিমেন্টগুলোকে নাম দেওয়া (অনেক সময় যাকে "ট্যাগ" বলা হয়) ভেক্টরের তুলনায় অ্যারের ক্ষেত্রে বেশি দেখা যায়:
list(x = 5.3, y = 4.2, color = "blue")
#> $x
#> [1] 5.3
#> $y
#> [1] 4.2
#> $color
#> [1] "blue"
তবে ট্যাগ ঐচ্ছিক; ট্যাগ না দিলে R শুধু ইনডেক্স নম্বর ব্যবহার করে:
list(5.3, 4.2, "blue")
#> [[1]]
#> [1] 5.3
#> [[2]]
#> [1] 4.2
#> [[3]]
#> [1] "blue"
এটি করার তিনটি উপায় আছে, প্রত্যেকটি ভিন্ন ভিন্ন প্রসঙ্গে কাজে লাগে।
$tag নোটেশন দিয়েট্যাগের নাম আগে থেকেই জানা থাকলে এটি খুবই প্রচলিত।
point <- list(x = 5.3, y = 4.2, color = "blue")
#> point$x
#> [1] 5.3
#> point$color
#> [1] "blue"
[[tag]] নোটেশন দিয়েএর সুবিধা হলো, ট্যাগের নাম রানটাইমে বেছে নেওয়া যায়। লক্ষ্য করুন, এখানে বন্ধনী দুবার ব্যবহৃত হয়েছে।
want <- "y"
point[[want]] # same as point$y
#> [1] 4.2
অ্যারেতে ট্যাগ থাকুক বা না থাকুক, এটি কাজ করে। এখানেও বন্ধনী দুবার ব্যবহৃত হয়েছে।
point[[3]] # same as point$color
#> [1] "blue"
সহজ: কোনো এলিমেন্টে অ্যাসাইন করলে সেটি আগে থেকে থাকলে বদলে যায়, আর নতুন হলে যুক্ত হয়।
point$color <- "red"
point$trust <- TRUE
# str() gives more compact output than the default display
str(point)
#> List of 4
#> $ x : num 5.3
#> $ y : num 4.2
#> $ color: chr "red"
#> $ trust: logi TRUE
মুছে ফেলতে হলে, যে এলিমেন্টটি দরকার নেই সেটিতে NULL অ্যাসাইন করুন।
point$trust <- NULL
str(point)
#> List of 3
#> $ x : num 5.3
#> $ y : num 4.2
#> $ color: chr "red"
vector ক্লাসটিকে কারিগরি দিক থেকে atomic vector বলা হয়, কারণ এটি শুধু অ্যাটমিক মান ধারণ করতে পারে: numeric, character, boolean ইত্যাদি।
যেহেতু একটি list-এ অন্য অ্যারে থাকতে পারে, তাই এটিকে recursive vector নামেও ডাকা হয়।
এটি শুধু নামকরণের একটি কারিগরি বিষয়ই নয়, বরং মনে করিয়ে দেয় যে অ্যারের গঠন ইচ্ছেমতো জটিল হতে পারে। অ্যারের কোনো এলিমেন্ট অ্যাক্সেস করলে কী পাওয়া যাবে, সেটি বোঝার দায়িত্ব প্রোগ্রামারের।
উপরের কিছু উদাহরণে অ্যারের এলিমেন্ট অ্যাক্সেস করতে দ্বৈত বন্ধনী [[ ]] ব্যবহার করা হয়েছে।
এটি এলিমেন্টটিকে তার মূল টাইপে সমতল করার চেষ্টা করে, যা তখনই কাজে লাগে যখন আপনি শুধু একটি সংখ্যা বা একটি স্ট্রিং চান।
একক বন্ধনী [ ] ব্যবহার করলে এই সমতলকরণ হয় না, এবং ফেরত পাওয়া মানটি হবে একটি সাব-অ্যারে।
point[["color"]]
#> [1] "red" # flattened
point["color"]
#> $color
#> [1] "red" # sublist
সাব-অ্যারে যে নতুন R প্রোগ্রামার চান এমন কিছু নয়, তবুও এটি সম্পর্কে সচেতন থাকুন।
সর্বোচ্চ নমনীয়তার জন্য, R-এর অনেক স্ট্যান্ডার্ড ফাংশনই একটি list রিটার্ন করে, এমনকি এখানে যেমন একটি মাত্র অ্যাটমিক মান থাকলেও।
একটি ভেক্টরে রূপান্তর করার দুটি উপায় আছে।
[[1]] দিয়ে প্রথম এলিমেন্টটি নিনunlist() ফাংশনটি ব্যবহার করুন।pt <-point["color"]
pt[[1]]
#> [1] "red" # simple 1-element vector
unlist(pt)
#> color
#> "red" # 1-element vector with name
unlist() ব্যবহারে সাবধান থাকুন।
এই সহজ ক্ষেত্রে গঠন সমতল করা কাজে লাগে, তবে আরও জটিল অ্যারে এলিমেন্টের ক্ষেত্রে এটি অপ্রত্যাশিত ফল দিতে পারে।
একটি list, একটি অ্যাটমিক vector-এর মতোই, একটানা জায়গায় সংরক্ষিত হয়। পার্থক্য হলো, সংখ্যাগত ও বুলিয়ান ভেক্টর মান সংরক্ষণ করে, কিন্তু অ্যারে মেমরির অন্য কোথাও থাকা অবজেক্টের রেফারেন্স সংরক্ষণ করে।
এটি জানা R ব্যবহারকারীর জন্য খুব একটা গুরুত্বপূর্ণ নয়, তবে Exercism-এর মতো বহুভাষিক কমিউনিটিতে অন্য ভাষার সাথে পরিচিত প্রোগ্রামারদের জন্য এটি সহায়ক হতে পারে।