سؤال
أجد نفسي باستخدام حلقات PHP مثل الكثير في Ruby وتشعر بالخطأ عندما تكون بقية اللغة أنيقة للغاية. أنا ينتهي مع رمز مثل هذا:
conditions_string = ''
zips.each_with_index do |zip, i|
conditions_string << ' OR ' if i > 0
conditions_string << "npa = ?"
end
# Now I can do something with conditions string
أشعر أنني يجب أن أكون قادرا على فعل شيء مثل هذا
conditions_string = zips.each_with_index do |zip, i|
<< ' OR ' if i > 0
<< "npa = ?"
end
هل هناك طريقة "أنيقة" لتعيين متغير مع كتلة في روبي؟
المحلول
لا يبدو أنك تصل zip
في حلقة الخاص بك، لذلك يجب أن تعمل ما يلي:
conditions_string = (['npa = ?'] * zips.length).join(' OR ')
إذا كنت بحاجة إلى الوصول إلى zip
, ، ثم يمكنك استخدام:
conditions_string = zips.collect {|zip| 'npa = ?'}.join(' OR ')
نصائح أخرى
نظرا لأنك لا تستخدم فعليا قيمة الرمز البريدي، سأقترح
zips.map {|zip| "npa = ?" }.join(" OR ")
ولكن بشكل عام أقترح النظر في وظيفة حقن # العددية لتجنب هذا النوع من الحلقات.
أول شيء اعتقدت أنه كان هذا:
a = %w{array of strings} => ["array", "of", "strings"]
a.inject { |m,s| m + ' OR ' + s } => "array OR of OR strings"
ولكن هذا يمكن القيام به مع فقط
a.join ' OR '
وبينما أعتقد أنك ستحتاج إلى إنشاء ذلك قريبا، لتكرار مثالك بالضبط، قد استخدم فقط:
([' npa = ? '] * a.size).join 'OR'
على الرغم من أن البعض الآخر قد قدم المزيد من الحلول الاصطلاحية لمشكلتك المحددة، فهناك في الواقع طريقة رائعة Object#instance_eval
, ، وهي خدعة قياسية تستخدم العديد من Ruby DSLS. يضع self
إلى جهاز الاستقبال instance_eval
داخل كتلة لها:
مثال قصير:
x = ''
x.instance_eval do
for word in %w(this is a list of words)
self << word # This means ``x << word''
end
end
p x
# => "thisisalistofwords"
انها لا تغطي كل شيء في الطريق في الطريق بيرل $_
هل، لكنه يسمح لك بإرسال طرق ضمنيا إلى كائن واحد واحد.
في 1.8.7+ يمكنك استخدام each_with_object
إنه يحل محل المصطلح "حقن" DigitalRoss مع هذا:
a = %w{hello my friend} => ["hello", "my", "friend"]
a.each_with_object("") { |v, o| o << v << " NOT " } => "hello NOT my NOT friend NOT"