روبي: كيف يمكنني استخدام الرموز لتمثيل الأشياء في مجموعة؟
سؤال
ولدي مجموعة من المصفوفات التي تبدو مثل هذا:
fruits_and_calories = [
["apple", 100],
["banana", 200],
["kumquat", 225],
["orange", 90]
]
وأود أيضا أن يكون طريقة أريد أن تحتج على كل عنصر من المصفوفة:
fruits_and_calories.each do |f| eat(f[0], f[1])
وأود حقا أن تكون قادرا على أن تقول شيئا مثل:
fruits_and_calories.each do |f| eat(f[:name], f[:calories])
هل هناك طريقة أستطيع أن سحب هذا دون الحاجة إلى تغيير كل عنصر في مجموعة (على سبيل المثال، من خلال بالتكرار وذلك من خلال إضافة بطريقة أو بأخرى الرموز في)؟ أو، اذا كان هذا صعبا للغاية، وهناك بديل أفضل؟
المحلول
وأفضل الجواب هو عدم استخدام صفيف في كل شيء، ولكن لاستخدام تجزئة:
fruits_and_calories = { :apple => 100,
:banana => 200,
:kumquat => 225,
:orange => 90}
fruits_and_calories.each do |name, calories|
eat(name, calories)
end
نصائح أخرى
ودون تغيير بنية البيانات في كل شيء، هل يمكن أن تغيير الحجج كتلة لتحقيق نفس الشيء:
fruits_and_calories.each do |name, calories| eat(name, calories); end
ويعمل هذا لأن روبي لصناعة السيارات في توسيع صفائف الداخلية ([ "تفاحة"، 100]، الخ) في قائمة وسيطة لكتلة ( 'القيام | اسم والسعرات الحرارية | ... نهاية'). هذا هو خدعة أن روبي الموروثة من اللثغة، والمعروفة باسم "الحجج الإتلاف.
والجواب بيستو في (استخدام تجزئة) هو فكرة جيدة، ولكن أعتقد أنني كنت تفضل استخدام البنية.
Fruit = Struct.new(:name, :calories)
fruits = [
Fruit.new("apple", 100),
Fruit.new("banana", 200),
Fruit.new("kumquat", 225),
Fruit.new("orange", 90)
]
fruits.each {|f| eat(f.name, f.calories)}
وهذا يفسح المجال أيضا لتغيير eat
من أخذ كل من اسم والسعرات الحرارية، لاتخاذ مثيل الفاكهة:
fruits.each {|f| eat(f)}
هل هناك سبب ما <م> يجب م> يكون صفيف، في حد ذاته؟ ويبدو أن تصرخ أن تكون تجزئة، أو فئة للفاكهة.
وفهرسة صفيف دائما الأرقام، بقدر ما أعرف باستخدام مجموعة موحدة من غير الممكن.
وأنا شخصيا كنت مجرد اختيار باستخدام تعليق فوق الرمز إلى التلميح ما و [0] وو [1] لتقف على.
ولكن إذا كنت الجحيم مصممة على فعل ذلك أعتقد أن بعض بطة الكتابة على أعمال الطبقة صفيف:
class Array
def name ; self[0] ; end
def calories ; self[1] ; end
end
# then call it with:
fruits_and_calories.each {|f| eat(f.name, f.calories) }