سؤال

أتلاعب بالمصفوفات والتجزئة كثيرًا في روبي وينتهي بي الأمر ببعض التعليمات البرمجية التي تبدو كما يلي:

sum = two_dimensional_array.select{|i|
  i.collect{|j|
    j.to_i
  }.sum > 5
}.collect{|i|
  i.collect{|j|
    j ** 2
  }.average
}.sum

(دعونا نتظاهر جميعًا بأن نموذج التعليمات البرمجية أعلاه أصبح منطقيًا الآن...)

المشكلة هي أنه على الرغم من أن TextMate (المحرر المفضل لدي) يلتقط بشكل بسيط {...} أو do...end الكتل بسهولة تامة، لا يمكن معرفة (وهو أمر مفهوم لأنني حتى لا أستطيع العثور على طريقة "صحيحة" لطي ما ورد أعلاه) حيث تبدأ الكتل المذكورة أعلاه وتنتهي في طيها.

كيف يمكنك طي نموذج التعليمات البرمجية أعلاه؟

ملاحظة:مع الأخذ في الاعتبار أنه يمكن أن يحتوي على مستويين من الطي، فأنا أهتم فقط بالمستويين المتتاليين الخارجيين (الكتل التي تحتوي على i)

هل كانت مفيدة؟

المحلول

لكي نكون صادقين، فإن الشيء الملتوي ربما يكون مربكًا لـ TextMate بقدر ما يربك أي شخص آخر يتعين عليه الحفاظ عليه، وهذا يشملك في المستقبل.

عندما ترى شيئًا ما يتحول إلى قيمة واحدة، فهذه حالة جيدة لاستخدام Enumerable#inject.

sum = two_dimensional_array.inject(0) do |sum, row|
  # Convert row to Fixnum equivalent
  row_i = row.collect { |i| i.to_i }

  if (row_i.sum > 5)
    sum += row_i.collect { |i| i ** 2 }.average
  end

  sum # Carry through to next inject call
end

الأمر الغريب في مثالك هو أنك تستخدم التحديد لإرجاع المصفوفة الكاملة، والتي يُزعم أنها تم تحويلها باستخدام to_i، لكن في الواقع Enumerable#select لا يفعل شيئًا من هذا القبيل، وبدلاً من ذلك يرفض أي شيء ترجع فيه الدالة صفرًا.أفترض أن هذا ليس من قيمك.

اعتمادًا أيضًا على كيفية تنفيذ أسلوب .average الخاص بك، قد ترغب في زرع استدعاء الحقن بـ 0.0 بدلاً من 0 لاستخدام قيمة الفاصلة العائمة.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top