شروع elixir : آشنایی بیشتر با لیست ها

با درود خدمت شما دوستان گرامی . این بخش از آموزش می رسه به آشنایی بیشتر با لیست ها . تا جایی که امکان داشت ترجمه و شبهه کد های ساده از اینترنت و کتاب و ویدیو پیدا کردم و قرار دادم .

قبل از خواندن این مطالب لطفا آموزش های قبلی در لینک زیر را مطالعه کنید
http://devheroes.club/c/other-programming-languages/elixir

#آشنایی و آموزش سریع الکسیر

##لیست ها

وقتی یک برنامه نویس در زبان های مختلف به لیست ها می رسد سعی می کند با دانش های قدیمی خودش به هر صورت شده نیاز های خودش را بر طرف کند . برای خیلی از ما ها پیش آماده که با یادگیری فقط سینتکز یک آرایه لیست یا هرچیزی که برایش اسم می گذاریم دیگر به سمت امکانات آن زبان نمی رویم تا اینکه نیاز شدید پیدا کنیم.

اما چرا باز دوباره به لیست ها برگشتیم و این بار برای ما چه چیز جدیدی هست که مجبور به آزمون و خطا و درک عمیق تر داریم ؟ راه درست ! بله elixir در لیست ها سعی کرده برای مشکلاتی که در آینده برای شما پیش می آید راه درستی را از پایه تعریف کند . این راه درست از مبانی اولیه هست نه یک فانکشن معمولی برای جدا کردن چند عدد و چاپ آن ها پس ارزش این را دارد که دوباره تمرین و همینطور دقت بیشتری بر روی آن شود

توجه : از این فصل به بعد بیشتر از اینکه متن و توضیح باشه , کد ها قرار می گیرند و یک توضیح یک خطی یا دو خطی دارند . به همین دلیل نیاز هست فصل های قبلی کامل تمرین شده باشند تا دچار مشکل نشوید

###Heads and Tails

پیش از این در اموزش های قبلی به این مورد اشاره کردیم که امکان دارد یک لیست از نوع خالی باشد یا شامل یک Head و Tail در خود باشد .

Head دارای یک مقدار و Tail خودش یک لیست می باشد . این تعریف از نوع بازگشتی می باشد. ( این بخش بیشتر مفهوم روش خوداتکایی را بیان می کند)

توجه : یک لیست خالی را قبلا به صورت [] نشان دادیم .

حال برای درک بهتر به سمت قطعه کد ها برای این بخش برویم :

iex> [ 3 | [] ]
[3]

به کد بالا توجه کنید . عدد سه را پایپ کردیم به یک آرایه خالی و در جواب برای ما یک لیست 3 برگرداند

حال به مثال زیر توجه کنید :

iex> [ 2 | [3 | [] ] ]
[2, 3]

و در مثال بالا جواب 2, 3 در یک لیست . شاید بگویید این یک کار بسیار کوچک و ناکارامدی هست ولی ممکن هست در همان لحظه یک صدای کوچکی در ذهن شما بیاید که بگویید برای این مورد می توان کار های بسیار زیادی کرد . کار های جادویی.

حال بیایید به سمت پترن ماچین برویم به مثال زیر توجه کنید :

iex> [a, b, c] = [1, 2, 3]
[1, 2, 3]

حال شما اگر a , b ,c را صدا بزنید هر کدام از عدد هایی که به آن بایند کردید پدیدار می شود.

اکنون با مثال های بالا می تونیم head را در یک لیست به کار ببریم

iex> [ head | tail] = [1,2,3,4,5,6]
[1, 2, 3, 4, 5, 6]

حال head را صدا می زنیم :

iex> head
1

و همینطور tail

iex> tail
[2, 3, 4, 5, 6]

اگر توجه کرده باشید سمت چپ از بدنه لیست به head و ادامه بدنه لیست به tail داده شد . حال شاید بگویید چه چیز بی ارزشی این چه بدرد من و کد های من می خورد .

####تجربه شخصی :
من هم اول در کتاب این مبحث را خواندم که همین مقدار بود که ترجمه کردم . پیش خودم گفت خوب یک سرفصل به این اختصاص داده شد برای همین !! که چی بشه ؟ ولی بعد از دیدن چند پروژه کوچک و بزرگ در ویدیو های آموزشی متوجه شدم اگر واقعا این مورد در الکسیر نبود ضعف بسیاری در کد های من پدیدار می شد .

به عنوان مثال شما کدی را لود می کنید و بعد از آن اولین پارامتر وضعیت شما :ok یا :error بر می گرداند و همینطور در بدنه سمت چپ که شاید ندونید دقیقا چی بر می گردد مثلا ( پیغام خطا - در کجا پیش آماده - زمان و … ) برای شما بازگشت می کند . به همین سادگی می توانید با head, tail کلش را در یک متغییر قرار دهید و از آن استفاده کنید.
آیا فکر می کنید نیاز به توضیح بیشتر هست ؟ واقعا جذاب نیست ؟

####توجه : این یک بازی برای ساخت و کنترل یک لیست نامتنهایی می باشد

به مثال زیر توجه کنید . از پترن ساخته شده می خواهیم در فانکشن ها استفاده کنیم و قدرت آن را نمایش بدهیم برای اینکه کد به صورت دقیق منظور مارا برساند ما در فانکشن دوم هر عددی را به علاوه یک می کنیم . دلیل این کار در بالا مطرح شده . برای یاداوری باید بگویم شما از یک لیست به یک لیست [] انتقال پیدا می کنید و پایپ می شوید . پس اندازه شما چیزی هست که در کد زیر قرار می گیرد :

# my blog  : https://trangell.com/fa/
# public : http://devheroes.club
defmodule MyList do
  def len([]), do: 0 
  def len([_head|tail]), do: 1 + len(tail)
end

IO.puts(MyList.len([])) # ==> 0 
IO.puts(MyList.len([1,2,3,4])) # ==> 4 

نکته : اگر در کد بالا توجه کرده باشید من قبل از head یک آندراسکور قرار دادم ( ـ ) و دلیل آن هم جلوگیری از ارور اینکه چرا head را استفاده نکردم است. همانطور که در مقالات اولیه توضیح دادیم شما با قرار دادن یک آندر اسکور قبل از متغیر یا پتر . این فرمان را می دهید که در نظر گرفته نشود.

کمی کد هامون تقویت کنیم . به نمونه کد زیر اوجه کنید

# my blog  : https://trangell.com/fa/
# public : http://devheroes.club
defmodule MyList do
  def len([]), do: 0 
  def len([_head|tail]), do: 1 + len(tail)

  # Build a List

  def square([]),              do: []
  def square([ head | tail ]), do: [ head*head | square(tail) ]

  def add_1([]),              do: [] 
  def add_1([ head | tail ]), do: [ head+1 | add_1(tail) ]

  def map([], _func),             do: []
  def map([ head | tail ], func), do: [ func.(head) | map(tail, func) ] 
end

IO.puts(MyList.len([])) 					# ==> 0
IO.puts(MyList.len([1,2,3,4])) 				# ==> 4
IO.puts(MyList.len(["cat" , "dog"])) 		# ==> 2

نکته : چون کد های جدید به فایل اضافه شده هست حتما دوباره کامپیال کنید تا ارور پیدا نکنید.

یکی دو دقیقه کد های بالا را بخوانید و بعد برای خودتان تحلیل کنید و بعد از آن مراحل زیر را انجام بدهید

ساخت یک لیست :

iex(6)> MyList.square([])
[]

و :

MyList.square([4,5,6])
[16, 25, 36]

و تست فانکشن ها

iex> MyList.add_1([1000])  
[1001]

و

iex> MyList.add_1([1000,2,3,4])
[1001, 3, 4, 5]

و حالا برای استفاده از فانکشن map

iex> MyList.map [1,2,3,4], fn (n) -> n + 1 end 
[2, 3, 4, 5]

فرض بر اینکه شما تا حالا کد های بالا رو هیچ کدوم کامنت نکردید و تست نکردید و فقط روزنامه واری مطالعه کردید برای درک شما یکی از کد هایی که یک جمع کننده هست و همینطور موارد بالا را در خودش دارد تحلیل می کنیم .

مثال :
ما در اینجا می خواهیم یک لیست درست شود و اعداد داخل لیستی که وارد می کنیم باهم جمع کرده و یک خروجی بدهد

def sum([], total), do: total
def sum([ head | tail ], total), do: sum(tail, head+total)

در اولین فانکشن ما یک آرایه خالی ساختیم و در دومین فانکشن لیست خالی که ساختیم را پر کردیم و بعد آن را جمع نمودیم و خروجی به ما یک عدد برگشت داده است

iex> MyList.sum([1,2,3,4,5], 0)
15

با تشکر که تا اینجا مقالات با بنده بودید . دوستان محترم برخی از ترجمه های این کتاب بالاتر از سطح سواد بنده هست و آنقدر قدرت برای ترجمه آن ها ندارم به همین علت سعی می کنم بخاطر حجم ۱۰۰۰ صفحه ای کتاب بیشتر به سمت موارد کاربردی بروم و برخی از موارد را فیلتر کنم . به نظرم تلفیقی از مطالب گفته شده با داکیومنت می تواند برای افرادی که دنبال درک عمیق تری از این زبان هستند مفید واقع شود
بنده سعی بر این دارم که تا جایی که ممکنه کتاب به زبان فارسی برگشت داده شود.

دانلود pdf این آموزش

اصلاحیه

دوستان در تعریف head چند اصلاحیه انجام شد که در فایل pdf وجود ندارد با تشکر.

#منابع بیشتر :

الکسیر :


https://gist.github.com/toomaj/b084e49bd1e4f82a3a730860684cbc18

همینجا از دوست خوبمون @toomaj تشکر می کنم بخاطر پیدا کردن مشکلات در متن و همینطور ارسال منابع بیشتر و اصلاحیه هایی که ارسال کردند .

2 پسندیده