Enum وحدة مفيدة جدًا توفّر مجموعة من الخوارزميات للتعامل مع القوابل للتعداد. فهي تقدّم الترتيب والتصفية والتجميع والعدّ والبحث وإيجاد القيم الصغرى والعظمى، والكثير غير ذلك.
بشكل عام، القابل للتعداد هو أي بيانات يمكن التكرار عليها، أي مجموعة. في Elixir، القابل للتعداد هو أي نوع بيانات يطبّق بروتوكول Enumerable. وأكثرها شيوعًا هي القوائم والخرائط.
تقبل العديد من دوال Enum دالةً كوسيط.
Enum.all?([1, 2, 3, 4, 5], fn x -> x > 3 end)
# => false
أكثر دوال Enum شيوعًا هي map وreduce.
map/2تتيح لك Enum.map/2 استبدال كل عنصر في قابل للتعداد بعنصر آخر. الوسيط الثاني لـEnum.map/2 هو دالة تقبل العنصر الأصلي وتُرجع بديله.
reduce/3تتيح لك Enum.reduce/3 اختزال قابل التعداد بأكمله إلى قيمة واحدة. ولتحقيق ذلك، يُستخدم متغير خاص يُسمّى المراكم. ويحمل المراكم الحالة الوسيطة للاختزال بين التكرارات.
الوسيط الثاني لـEnum.reduce/3 هو القيمة الابتدائية للمراكم. والوسيط الثالث هو دالة تقبل عنصرًا ومراكمًا، وتُرجع القيمة الجديدة للمراكم.
عند استخدام الخرائط مع دوال Enum، تُحوَّل الخريطة تلقائيًا إلى قائمة من الأزواج الثنائية {key, value}.
لإعادة تحويلها إلى خريطة، استخدم Enum.into/2. وEnum.into/2 دالة تحوّل قابل التعداد إلى قابل للتجميع، أي بنية بيانات تطبّق بروتوكول Collectable. ويمكن اعتبارها عكس Enum.reduce/3.
ولدى Enum أيضًا Enum.into/3. وEnum.into/3 نسخة مختلفة من Enum.into/2 تقبل دالة تحويل تُطبَّق أثناء تحويل قابل التعداد إلى قابل للتجميع.
بدلًا من استخدام Enum.into/3 أو Enum.map/2 مع Enum.into/2 لتطبيق تحويل (تعيين) على خريطة، يمكننا أيضًا استخدام دالة مخصّصة هي Map.new/2. وهي تعمل تمامًا مثل Enum.into/3 من حيث أنها تقبل قابلًا للتعداد ودالة تحويل، لكنها تُرجع دائمًا خريطة جديدة بدلًا من أن تتيح لنا اختيار قابل للتجميع.
أنت تدير متجر أزياء عبر الإنترنت. يقترب موسم التخفيضات السنوي الكبير، لذا عليك جرد مخزونك للتأكد من أنك مستعد.
تُمثَّل كل قطعة في المخزون بخريطة، والمخزون كله مصفوفة من هذه الخرائط.
%{
name: "White Shirt",
price: 40,
quantity_by_size: %{s: 3, m: 7, l: 8, xl: 4}
}
نفّذ الدالة sort_by_price/1. يجب أن تأخذ المخزون وتُرجع مرتبًا حسب سعر القطعة، تصاعديًا.
BoutiqueInventory.sort_by_price([
%{price: 65, name: "Maxi Brown Dress", quantity_by_size: %{}},
%{price: 50, name: "Red Short Skirt", quantity_by_size: %{}},
%{price: 50, name: "Black Short Skirt", quantity_by_size: %{}},
%{price: 20, name: "Bamboo Socks Cats", quantity_by_size: %{}}
])
# => [
# %{price: 20, name: "Bamboo Socks Cats", quantity_by_size: %{}},
# %{price: 50, name: "Red Short Skirt", quantity_by_size: %{}},
# %{price: 50, name: "Black Short Skirt", quantity_by_size: %{}},
# %{price: 65, name: "Maxi Brown Dress", price: 65, quantity_by_size: %{}}
# ]
بعد ترتيب مخزونك حسب السعر، لاحظت أنك أخطأت عند الجرد ونسيت تسجيل أسعار بعض القطع.
نفّذ الدالة with_missing_price/1. يجب أن تأخذ المخزون وتُرجع مصفوفة من القطع التي ليس لها أسعار.
BoutiqueInventory.with_missing_price([
%{price: 40, name: "Black T-shirt", quantity_by_size: %{}},
%{price: nil, name: "Denim Pants", quantity_by_size: %{}},
%{price: nil, name: "Denim Skirt", quantity_by_size: %{}},
%{price: 40, name: "Orange T-shirt", quantity_by_size: %{}}
])
# => [
# %{price: nil, name: "Denim Pants", quantity_by_size: %{}},
# %{price: nil, name: "Denim Skirt", quantity_by_size: %{}}
# ]
لاحظت أن بعض أسماء القطع تحتوي على كلمة لم تعد ترغب في استخدامها. الآن عليك تحديث كل أسماء القطع التي تحتوي على تلك الكلمة.
نفّذ الدالة update_names/3. يجب أن تأخذ المخزون، والكلمة القديمة التي تريد إزالتها، والكلمة الجديدة التي تريد استخدامها بدلًا منها. ويجب أن تُرجع مصفوفة من القطع بأسماء محدّثة.
BoutiqueInventory.update_names(
[
%{price: 40, name: "Black T-shirt", quantity_by_size: %{}},
%{price: 70, name: "Denim Pants", quantity_by_size: %{}},
%{price: 65, name: "Denim Skirt", quantity_by_size: %{}},
%{price: 40, name: "Orange T-shirt", quantity_by_size: %{}}
],
"T-shirt",
"Tee"
)
# => [
# %{price: 40, name: "Black Tee", quantity_by_size: %{}},
# %{price: 70, name: "Denim Pants", quantity_by_size: %{}},
# %{price: 65, name: "Denim Skirt", quantity_by_size: %{}},
# %{price: 40, name: "Orange Tee", quantity_by_size: %{}}
# ]
كانت بعض القطع تُبيع جيدًا بشكل خاص، لذا طلبت المزيد منها بجميع المقاسات.
نفّذ الدالة increase_quantity/2. يجب أن تأخذ قطعة واحدة وعددًا n، وتُرجع تلك القطعة مع زيادة الكمية لكل مقاس بمقدار n.
BoutiqueInventory.increase_quantity(
%{
name: "Polka Dot Skirt",
price: 68,
quantity_by_size: %{s: 3, m: 5, l: 3, xl: 4}
},
6
)
# => %{
# name: "Polka Dot Skirt",
# price: 68,
# quantity_by_size: %{l: 9, m: 11, s: 9, xl: 10}
# }
لمعرفة المساحة التي تحتاجها في المخزن، عليك معرفة إجمالي ما لديك من كل قطعة.
نفّذ الدالة total_quantity/1. يجب أن تأخذ قطعة واحدة وتُرجع عدد القطع الإجمالي لديك، بأي مقاس.
BoutiqueInventory.total_quantity(%{
name: "Red Shirt",
price: 62,
quantity_by_size: %{s: 3, m: 6, l: 5, xl: 2}
})
# => 16
سجّل في Exercism لتتعلّم وتتقن Elixir عبر 58 مفهومًا168 تمرينًا، وإرشاد بشري حقيقي، وكل ذلك مجانًا.