Do you want to pick up from where you left of?
Take me there

கணம்

எண்ணக்கூடிய தொகுப்புகளின் கணக்கீட்டிற்குப்பயன்படும் படிமுறைகள்.

கணம்

கணம் என்பது எண்ணக்கூடியதொகுப்புகளின் கணக்கீட்டிற்குத்தேவையான எழுபதுக்கும்மேற்பட்ட செயற்கூறுகள் கொண்ட கூறு ஆகும். டப்பில்களைத்தவிர நாம் முந்தைய பாடத்தில்படித்த, அனைத்து தொகுப்புகளும் எண்ணக்கூடியதொகுப்புகளே.

கணம் கூறிலுள்ள ஒருசிலமுக்கியமான செயற்கூறுகளை மட்டுமே இங்கு நாம் அறியவிருக்கிறோம். எனினும், அவையனைத்தையும் நாம் IEx வழியே கண்டுகொள்ளமுடியும்.

iex> Enum.__info__(:functions) |> Enum.each(fn({function, arity}) ->
...>   IO.puts "#{function}/#{arity}"
...> end)
all?/1
all?/2
any?/1
any?/2
at/2
at/3
...

இதிலிருந்து பெருவாரியான செயல்பாடுகள் உள்ளதென்பதை நாம் அறியலாம். இதற்கு ஒரு முக்கியகாரணம் உள்ளது. செயல்பாட்டு நிரலாக்கத்தின் மையக்கருவாகவும், மிகப்பயனுள்ள கூறாகவும் கணங்கள் உள்ளன. இவற்றையும், ஆவணப்படுத்தலை முதல்தரகுடிமக்களாக கருதுதல், போன்ற எலிக்சரின் இன்னபிற சிறப்பம்சங்களையும் சேர்த்து பயன்படுத்தும்போது நிரலர்களுக்கு அதீததிறனையளிக்கின்றன என்பதில் சந்தேகமில்லை.

கணங்களின் செயற்கூறுகளின் முழுமையான பட்டியலுக்கு அதன் அதிகாரபூர்வ ஆவணங்களைக்காணலாம். கணங்களின் காலந்தாழ்ந்த கணக்கீடுகளுக்கு தாரைகள் என்ற கூற்றினைப்பயன்படுத்தலாம்.

all?

all?/2, என்ற செயற்கூறையோ, கணங்களிலுள்ள இன்னபிற செயற்கூறுகளையோ பயன்படுத்தும்போது, ஒரு தொகுப்பிலுள்ள உருப்படிகள் ஒவ்வொன்றின் மீதும் செயல்படுகின்ற ஒரு செயற்கூறினை, அதற்கு உள்ளீட்டு உருபாக அனுப்பவேண்டும். all?/2, ல் கொடுக்கப்பட்ட செயற்கூற்றினை மதிப்பிடும்போது, எல்லா உருப்படிகளுக்கும் true என்ற மதிப்பை திருப்பியனுப்பினால் மட்டுமே all?/2ன் மதிப்பு true என்றிருக்கும். ஏதேனும் ஒரு உருப்படி false என்ற மதிப்பை திருப்பியனுப்பினால்கூட, all?/2 ன் மதிப்பு false ஆகிவிடும்:

iex> Enum.all?(["foo", "bar", "hello"], fn(s) -> String.length(s) == 3 end)
false
iex> Enum.all?(["foo", "bar", "hello"], fn(s) -> String.length(s) > 1 end)
true

any?

all?/2  ஐப்போல இல்லாமல், தொகுப்பின் ஏதேனும் ஒரு உருப்படி true என்ற மதிப்பை திருப்பியனுப்பினாலும், any?/2 செயற்கூறு true ஐ திருப்பியனுப்பும்:

iex> Enum.any?(["foo", "bar", "hello"], fn(s) -> String.length(s) == 5 end)
true

chunk_every

ஒரு தொகுப்பிலுள்ள உருப்படிகளை சிறுசிறு குழுக்களாகப்பிரிப்பதற்கு, chunk_every/2 பயன்படுகிறது:

iex> Enum.chunk_every([1, 2, 3, 4, 5, 6], 2)
[[1, 2], [3, 4], [5, 6]]

இச்செயல்கூறுக்கு சில தெரிவுகளை அனுப்பலாம். தெரிவுகளை ஏற்கும், chunk_every/4 செயற்கூற்றைப்பற்றி நாம் இங்கே படிக்கப்போவதில்லை. அவற்றை அறியவேண்டுமெனில்ப், அதன் அதிகாரபூர்வ ஆவணத்தை பார்த்துக்கொள்ளவும்.

chunk_by

ஒரு தொகுப்பிலுள்ள உருப்படிகளை ஒரு காரணியைப்பொருத்து, சிறுசிறு குழுக்களாகப்பிரிப்பதற்க்கு இச்செயற்கூறு (chunk_by/2) பயன்படுகிறது. ஒரு தொகுப்பையும், செயற்கூறையும் உள்ளீடாக எடுத்துக்கொள்கிறது. இரு உருப்படிகளுக்கிடையே, செயற்கூற்றின் மதிப்பு மாறுபடும்போது, ஒரு புதிய குழு உருவாக்கப்பட்டு, அடுத்த உருப்படி மதிப்பிடப்படுகிறது.

iex> Enum.chunk_by(["one", "two", "three", "four", "five"], fn(x) -> String.length(x) end)
[["one", "two"], ["three"], ["four", "five"]]
iex> Enum.chunk_by(["one", "two", "three", "four", "five", "six"], fn(x) -> String.length(x) end)
[["one", "two"], ["three"], ["four", "five"], ["six"]]

map_every

சிலசமயங்களில் குழுக்களாக பிரிப்பதுமட்டுமே போதுமானதாக இருப்பதில்லை. அச்சமயங்களில், map_every/3 என்ற செயற்கூறு பயனுள்ளதாக இருக்கலாம். தொகுப்பின் முதல் உருப்படியிலிருந்து, ஒவ்வொரு n ஆவது உருப்படியையும் எடுத்து கணக்கீடுகளுக்கு உட்படுத்த இது உதவுகிறது:

# Apply function every three items
iex> Enum.map_every([1, 2, 3, 4, 5, 6, 7, 8], 3, fn x -> x + 1000 end)
[1001, 2, 3, 1004, 5, 6, 1007, 8]

each

சிலசமயங்களில், ஒரு புதிய மதிப்பைத்தருவிக்கவேண்டிய அவசியம் இல்லாமல், தொகுப்புகளின் உருப்படிகளை ஒரு செயற்கூற்றுக்குள் உள்ளிடவேண்டியிருக்கலாம். அச்சமயங்களில், each/2 என்ற செயற்கூற்றைப்பயன்படுத்தலாம்:

iex> Enum.each(["one", "two", "three"], fn(s) -> IO.puts(s) end)
one
two
three
:ok

குறிப்பு: each/2 செயற்கூறு எப்போதும் :ok என்ற அணுவை திருப்பியனுப்பும்.

map

தொகுப்பிலுள்ள ஒவ்வொரு உருப்படியையும் செயற்கூற்றுக்கு உள்ளிட்டு, அதிலிருந்து கிடைக்கும் மதிப்புகளைத்திரட்டி புதியதொரு தொகுப்பைப்பெற map/2 என்ற செயற்கூறு உதவுகிறது:

iex> Enum.map([0, 1, 2, 3], fn(x) -> x - 1 end)
[-1, 0, 1, 2]

min

ஒரு தொகுப்பிலுள்ள மீச்சிறுமதிப்பைக்கண்டறிய min/1 என்ற செயற்கூற்றைப்பயன்படுத்தலாம்:

iex> Enum.min([5, 3, 0, -1])
-1

min/2 என்ற செயற்கூறும் min/1க்கு இணையானதே. ஆனால், இரண்டாவது உள்ளீட்டு உருபாக ஒரு செயற்கூற்றை ஏற்றுக்கொள்கிறது. கொடுக்கப்பட்ட தொகுப்பில் எந்த மதிப்புகளும் இல்லாதிருக்கும்போது, இந்த செயற்கூறு இயக்கப்பட்டு அதன் மதிப்பு திருப்பியனுப்படுகிறது.

iex> Enum.min([], fn -> :foo end)
:foo

max

ஒரு தொகுப்பிலுள்ள மீப்பெருமதிப்பை max/1 திருப்பியனுப்புகிறது:

iex> Enum.max([5, 3, 0, -1])
5

min/1க்கு min/2 உள்ளது போலவே, max/1க்கு இணையாக max/2 என்ற செயற்கூறு உள்ளது:

Enum.max([], fn -> :bar end)
:bar

reduce

reduce/3 என்ற செயற்கூற்றைக்கொண்டு ஒரு தொகுப்பிலுள்ள உருப்படிகளை ஒரு கணக்கீட்டிற்கு உட்படுத்தி, ஒற்றை மதிப்பைத்தருவிக்கலாம். அகுமுலேடர் என்ற விதைமதிப்பை (கீழ்கண்ட எடுத்துக்காட்டில், 10), இச்செயற்கூற்றுக்கு கொடுக்கவேண்டும். அகுமுலேடர் கொடுக்கப்படவில்லையெனில், தொகுப்பின் முதல் உருப்படி அகுமுலேடராக எடுத்துக்கொள்ளப்படும்:

iex> Enum.reduce([1, 2, 3], 10, fn(x, acc) -> x + acc end)
16

iex> Enum.reduce([1, 2, 3], fn(x, acc) -> x + acc end)
6

iex> Enum.reduce(["a","b","c"], "1", fn(x,acc)-> x <> acc end)
"cba1"

sort

தொகுப்புகளை எளிதாக வரிசைப்படுத்துவதற்காக இரண்டு செயற்கூறுகள் வழங்கப்பட்டுள்ளன.

sort/1 எர்லாங்கின் வரிசைப்படுத்தும்முறைமையைப்பயன்படுத்துகிறது:

iex> Enum.sort([5, 6, 1, 3, -1, 4])
[-1, 1, 3, 4, 5, 6]

iex> Enum.sort([:foo, "bar", Enum, -1, 4])
[-1, 4, Enum, :foo, "bar"]

sort/2 செயற்கூறு, நாம் உள்ளீட்டு உருபாக வழங்கும் செயற்கூற்றைப்பயன்படுத்தி வரிசைப்படுத்துகிறது:

# with our function
iex> Enum.sort([%{:val => 4}, %{:val => 1}], fn(x, y) -> x[:val] > y[:val] end)
[%{val: 4}, %{val: 1}]

# without
iex> Enum.sort([%{:count => 4}, %{:count => 1}])
[%{count: 1}, %{count: 4}]

uniq_by

கணங்களில் ஒருமுறைக்குமேல் வரும் உருப்படிகளை நீக்க uniq_by/2 செயற்கூற்றைப்பயன்படுத்தலாம்:

iex> Enum.uniq_by([1, 2, 3, 2, 1, 1, 1, 1, 1], fn x -> x end)
[1, 2, 3]
Caught a mistake or want to contribute to the lesson? Edit this lesson on GitHub!