MapSet مجموعهای از مقادیر یکتاست که مجموعهها را در Elixir نمایش میدهد.
میتواند مقادیری از هر نوع را در خود نگه دارد، بدون آنکه ترتیبی در کار باشد.
توجه کنید که ماژول Set هم وجود دارد، اما به نفع MapSet منسوخ شده است.
میتوانید با MapSet.new/0، MapSet.new/1 و MapSet.new/2 مجموعه بسازید و با MapSet.to_list/1 آنها را به فهرست تبدیل کنید.
MapSet.new()
# => MapSet.new([])
MapSet.new([2, 3, 3, 3, 1, 1, 2, "hello"])
# => MapSet.new([1, 2, 3, "hello"])
MapSet.new([2, 3, 3, 3, 1, 1, 2], fn n -> 10 * n end)
# => MapSet.new([10, 20, 30])
[2, 3, 3, 3, 1, 1, 2] |> MapSet.new() |> MapSet.to_list()
# => [1, 2, 3]
توجه کنید که چون MapSetها تصوری از ترتیب ندارند، MapSet.to_list/1 تضمین نمیکند فهرستی مرتب برگرداند.
میتوانید با MapSet.put/2 و MapSet.delete/2 عنصر اضافه یا حذف کنید.
میتوانید با توابع MapSet.size/1 و MapSet.member?/2 محتوای یک مجموعه را بررسی کنید و مجموعهها را با MapSet.equal?/2، MapSet.subset?/2 و MapSet.disjoint?/2 مقایسه کنید.
a = MapSet.new([1, 10])
b = MapSet.new([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
MapSet.size(b)
# => 10
MapSet.member?(a, 10)
# => true
MapSet.subset?(a, b)
# => true
MapSet.disjoint?(a, b)
# => false
MapSetها را میتوان با MapSet.union/2، MapSet.intersection/2، MapSet.difference/2 و MapSet.symmetric_difference/2 ترکیب کرد.
a = MapSet.new([1, 10, 100])
b = MapSet.new([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
MapSet.union(a, b)
# => MapSet.new([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 100])
MapSet.intersection(a, b)
# => MapSet.new([1, 10])
MapSet.difference(a, b)
# => MapSet.new([100])
MapSet.difference(b, a)
# => MapSet.new([2, 3, 4, 5, 6, 7, 8, 9])
MapSet.symmetric_difference(b, a)
# => MapSet.new([2, 3, 4, 5, 6, 7, 8, 9, 100])
میتوانید مجموعهها را با MapSet.filter/2، MapSet.reject/2 و MapSet.split_with/2 فیلتر و تقسیم کنید.
a = MapSet.new([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
even = fn n -> rem(n, 2) == 0 end
MapSet.filter(a, even)
# => MapSet.new([2, 4, 6, 8, 10])
MapSet.reject(a, even)
# => MapSet.new([1, 3, 5, 7, 9])
MapSet.split_with(a, even)
# => {MapSet.new([2, 4, 6, 8, 10]), MapSet.new([1, 3, 5, 7, 9])}
نوستالژیتان برای کارتهای Blorkemon™️ قرار نیست فروکش کند؛ حتی دوباره شروع به جمعآوری آنها کردهاید و دارید دوستانتان را هم با خودتان همراه میکنید.
در این تمرین، مجموعهی کارتها با یک MapSet نمایش داده میشود، چون وقتی هدفتان به دست آوردن همهی کارتهای موجود است، کارتهای تکراری اهمیتی ندارند.
شما واقعاً میخواهید دوستانتان هم به دیوانگی Blorkemon™️ شما بپیوندند و بهترین راه این است که با دادن یک کارت، مجموعهشان را راه بیندازید.
تابع GottaSnatchEmAll.new_collection را پیادهسازی کنید که یک کارت را به یک «مجموعه» تبدیل میکند.
GottaSnatchEmAll.new_collection("Newthree")
# => MapSet.new(["Newthree"])
وقتی مجموعهای داشته باشید، خودش جان میگیرد و باید بزرگ شود.
تابع GottaSnatchEmAll.add_card را پیادهسازی کنید که یک کارت و یک مجموعه میگیرد و یک «تاپل» با دو مقدار برمیگرداند: یک «مقدار منطقی» که نشان میدهد آیا کارت از قبل در مجموعه بوده است یا نه، و مجموعهای که کارت به آن اضافه شده است.
GottaSnatchEmAll.add_card("Scientuna", MapSet.new(["Newthree"]))
# => {false, MapSet.new(["Newthree", "Scientuna"])}
حالا که دوستانتان دوباره دیوانهی Blorkemon™️ شدهاند، میتوانید از این راه با معاملهی کارتها مجموعهی خودتان را بزرگ کنید.
هر معاملهای ارزش انجام دادن ندارد، یا اصلاً امکانپذیر نیست. نمیتوانید کارتی را که ندارید معامله کنید و نباید کارتی را با کارتی که از قبل دارید معامله کنید.
تابع GottaSnatchEmAll.trade_card را پیادهسازی کنید که دو کارت برای معامله (کارت شما و کارت آنها) و مجموعهی فعلی شما را میگیرد.
مقدار بازگشتی یک تاپل با دو مقدار است: یک مقدار منطقی که بیان میکند آیا معامله ممکن و ارزش انجام دادن دارد یا نه، و مجموعهای که در صورت انجام معامله به آن میرسید (حتی اگر در واقع ممکن نباشد).
GottaSnatchEmAll.trade_card("Scientuna", "Newthree", MapSet.new(["Scientuna"]))
# => {true, MapSet.new(["Newthree"])}
در یک بازار دستفروشی، انباری قدیمی از کارتها پیدا میکنید. باید کارتها را مرتب کنید و تکراریها را حذف کنید تا فهرست را با مجموعهتان مقایسه کنید.
تابع GottaSnatchEmAll.remove_duplicates را پیادهسازی کنید که فهرستی از کارتها را مرتب میکند و فهرستی از کارتهای مرتب و یکتا برمیگرداند.
GottaSnatchEmAll.remove_duplicates(["Newthree", "Newthree", "Newthree", "Scientuna"])
# => ["Newthree", "Scientuna"]
وقت آن است که به مجموعهتان ببالید.
تابع GottaSnatchEmAll.extra_cards را پیادهسازی کنید که مجموعهی شما و مجموعهی دیگری را میگیرد و تعداد کارتهایی را برمیگرداند که مجموعهی دیگر ندارد.
GottaSnatchEmAll.extra_cards(MapSet.new(["Scientuna"]), MapSet.new(["Newthree", "Scientuna"]))
# => 0
شما و دوستان علاقهمندتان به Blorkemon™️ دور هم جمع میشوید و از خودتان میپرسید کدام کارتها از همه رایجترند.
تابع GottaSnatchEmAll.boring_cards را پیادهسازی کنید که فهرستی از مجموعهها را میگیرد و فهرستی مرتب از کارتهایی را برمیگرداند که همهی مجموعهها دارند.
GottaSnatchEmAll.boring_cards([MapSet.new(["Scientuna"]), MapSet.new(["Newthree", "Scientuna"])])
# => ["Scientuna"]
آیا شما و دوستانتان روی هم همهی کارتهای Blorkemon™️ را دارید؟
تابع GottaSnatchEmAll.total_cards را پیادهسازی کنید که فهرستی از مجموعهها را میگیرد و تعداد کل کارتهای متفاوت در همهی مجموعهها را برمیگرداند.
GottaSnatchEmAll.total_cards([MapSet.new(["Scientuna"]), MapSet.new(["Newthree", "Scientuna"])])
# => 2
بهزودی برادرزادهتان به دیدنتان میآید و دلتان میخواهد او را تحت تأثیر قرار دهید. بچهها چیزهای براق را دوست دارند، نه؟ کارتهای Blorkemon™️ میتوانند براق باشند!
تابع GottaSnatchEmAll.split_shiny_cards را پیادهسازی کنید که یک مجموعه میگیرد و یک تاپل با دو فهرست از کارتهای مرتب برمیگرداند: یکی شامل همهی کارتهایی که با "Shiny" شروع میشوند و یکی شامل بقیهی کارتها.
GottaSnatchEmAll.split_shiny_cards(MapSet.new(["Newthree", "Scientuna", "Shiny Scientuna"]))
# => {["Shiny Scientuna"], ["Newthree", "Scientuna"]}