توصیفها
در الکسیر، توصیف لیستها قواعد نوشتاری برای زیباسازی زبان هستند. در این درس یاد میگیریم چگونه از توصیفها برای تکرار و تولید استفاده کنیم.
مبانی
اغلب میتوان از توصیفها^1 برای تولید گزارههای^2 کوتاه برای تکرارهای Enum
و Stream
استفاده کرد.
بیایید با نگاهی به یک توصیف ساده آغاز کنیم و سپس آن را بررسی کنیم:
iex> list = [1, 2, 3, 4, 5]
iex> for x <- list, do: x*x
[1, 4, 9, 16, 25]
اولین چیزی که متوجه میشویم استفاده از for
و یک تولیدکننده^3 است.
تولیدکننده چیست؟
تولیدکنندهها عبارتهایی^4 مانند x <- [1, 2, 3, 4]
هستند که در توصیفهای لیست یافت میشوند.
آنها مسئول تولید مقدار بعدی هستند.
خوشبختانه، توصیفها محدود به لیست نیستند؛ در واقع آنها با هر (چیز) قابل شمارشی^5 کار میکنند:
# Keyword Lists
iex> for {_key, val} <- [one: 1, two: 2, three: 3], do: val
[1, 2, 3]
# Maps
iex> for {k, v} <- %{"a" => "A", "b" => "B"}, do: {k, v}
[{"a", "A"}, {"b", "B"}]
# Binaries
iex> for <<c <- "hello">>, do: <<c>>
["h", "e", "l", "l", "o"]
مثل خیلی چیزهای دیگر در الکسیر، تولیدکنندهها از برای مقایسهی ورودی با متغیر سمت چپ از تطابق الگو استفاده می کنند. اگر تطابقی یافت نشود، مقدار مربوطه نادیده گرفته میشود:
iex> for {:ok, val} <- [ok: "Hello", error: "Unknown", ok: "World"], do: val
["Hello", "World"]
استفاده از چندین تولیدکننده هم امکانپذیر است، شبیه به حلقههای تو در تو:
iex> list = [1, 2, 3, 4]
iex> for n <- list, times <- 1..n do
...> String.duplicate("*", times)
...> end
["*", "*", "**", "*", "**", "***", "*", "**", "***", "****"]
برای نمایش بهتر اتفاقاتی که در حلقه میافتد، بیایید از IO.puts
برای نمایش دو مقداری که تولید میشوند استفاده کنیم:
iex> for n <- list, times <- 1..n, do: IO.puts "#{n} - #{times}"
1 - 1
2 - 1
2 - 2
3 - 1
3 - 2
3 - 3
4 - 1
4 - 2
4 - 3
4 - 4
توصیفهای لیست قواعدی برای زیباسازی زبان هستند و تنها باید هنگامی که مناسب است استفاده شوند.
پالایهها
میتوانید پالایهها^6 را نوعی محافظ برای توصیفها در نظر بگیرید.
هنگامی که یک مقدار پالایش شده false
یا nil
برمیگرداند، از لیست نهایی کنار گذاشته میشود.
بیایید در یک دامنه اعداد زوج را پیدا کنیم.
از تابع is_even/1
ماژول Integer برای بررسی زوج بودن مقدار استفاده میکنیم.
import Integer
iex> for x <- 1..10, is_even(x), do: x
[2, 4, 6, 8, 10]
مثل تولیدکنندهها، میتوان از چندین پالایه هم استفاده کرد. بیایید دامنهی مثال پیش را گسترش دهیم و سپس مقادیر را پالایش کنیم تا تنها اعدادی که هم زوج هستند هم بر ۳ بخشپذیر هستند، برجا بمانند.
import Integer
iex> for x <- 1..100,
...> is_even(x),
...> rem(x, 3) == 0, do: x
[6, 12, 18, 24, 30, 36, 42, 48, 54, 60, 66, 72, 78, 84, 90, 96]
کاربرد :into
چه میشود اگر بخواهیم چیزی به جز لیست تولید کنیم؟
با استفاده از گزینهی :into
میتوانیم این کار را انجام دهیم!
به عنوان یک قاعدهی کلی در نظر داشته باشید که :into
هر ساختار پیادهسازی کنندهی پروتکل Collectable
را میپذیرد.
بیایید با کمک :into
یک لیست کلمات کلیدی از یک نگاشت بسازیم:
iex> for {k, v} <- [one: 1, two: 2, three: 3], into: %{}, do: {k, v}
%{one: 1, three: 3, two: 2}
از آنجا که دودوییها پروتکل Collectable
را پیادهسازی میکنند، میتوانیم از توصیف لیست و :into
برای ساخت رشته استفاده کنیم:
iex> for c <- [72, 101, 108, 108, 111], into: "", do: <<c>>
"Hello"
همین! توصیف لیست راهی ساده و کوتاه برای پیمایش دستهها هستند.
Caught a mistake or want to contribute to the lesson? Edit this lesson on GitHub!