الفرز روبي مجموعة من الأشياء من قبل السمة التي يمكن النيل
سؤال
لدي مجموعة من الكائنات التي تحتاج إلى فرز حسب الموقف السمة التي يمكن أن يكون عدد صحيح أو النيل, و أنا في حاجة إلى الكائنات التي النيل يمكنها من أن تكون في نهاية الصفيف.الآن أستطيع أن قوة الموقف إلى عودة بعض القيمة بدلا من النيل حتى مجموعة.نوع لا تفشل ، ولكن إذا كنت تستخدم 0 كما أن هذا التقصير ، ثم يضع هذه الأشياء في الجزء الأمامي من هذا النوع.ما هي أفضل طريقة للقيام بذلك النوع ؟ يجب أن مجرد مجموعة النيل القيم إلى بعض عالية يبعث على السخرية رقم 'تقريبا' يضمن دائما أن يكون في نهاية المطاف ؟ أو هل هناك طريقة أخرى أنا يمكن أن تسبب مجموعة.نوع الأسلوب لوضع النيل سمة الكائنات في نهاية المصفوفة ؟ رمز يبدو مثل هذا:
class Parent
def sorted_children
children.sort{|a, b| a.position <=> b.position}
end
end
class Child
def position
category ? category.position : #what should the else be??
end
end
الآن, إذا كنت جعل 'آخر' شيء مثل 1000000000 ، ثم إنه على الأرجح سوف وضعها في نهاية المصفوفة, ولكن أنا لا أحب هذا الحل كما انها التعسفي
المحلول
وماذا عن في Child
تحديد <=>
أن تستند category.position
في حالة وجود category
، وفرز العناصر دون category
كما أكبر دائما من أولئك الذين لديهم category
؟
class Child
# Not strictly necessary, but will define other comparisons based on <=>
include Comparable
def <=> other
return 0 if !category && !other.category
return 1 if !category
return -1 if !other.category
category.position <=> other.category.position
end
end
وبعد ذلك في Parent
يمكنك الاتصال فقط children.sort
.
نصائح أخرى
وأود فقط قرص نوع لوضع البنود nil
الماضي. محاولة شيء من هذا القبيل.
foo = [nil, -3, 100, 4, 6, nil, 4, nil, 23]
foo.sort { |a,b| a && b ? a <=> b : a ? -1 : 1 }
=> [-3, 4, 4, 6, 23, 100, nil, nil, nil]
وهذا يقول: إذا أ و ب على حد سواء غير شيء الفرز لهم عادة ولكن إذا واحد منهم هو لا شيء، والعودة إلى الوضع الذي يفرز أن أحد أكبر
.أنا التعامل مع هذه الأنواع من الأشياء من هذا القبيل:
children.sort_by {|child| [child.position ? 0 : 1,child.position || 0]}
لنكون منصفين، وأنا لست على دراية جدا مع روبي، حتى تأخذ هذا الأمر أكثر من فكرة الخوارزمية بدلا من رمز واحد ... وإعادة كتابة: مشغل ما أن ما لديها روبي هذا أنظف
.ولا يمكنك فقط التحقق من وجود شيء في المقارنة:
class Parent
def sorted_children
children.sort{|a,b|( a and b ) ? a <=> b : ( a ? -1 : 1 ) }
end
end
وقام لاستخدام رمز Glenra، والتي تطبق نفس الشيء مثل الألغام ولكن في كمية أقل (وربما أسهل في القراءة) من التعليمات البرمجية.
وأنا لم تكن قد فعلت روبي في حين، ولكن هل يمكن تقسيم خالية التحقق من الفرز (والسماح فقط للأطفال # موقف للعودة لاغية):
def sorted_children
children.reject{|c| c.position.nil?}.sort_by(&:position) +
children.select{|c| c.position.nil?}
end
وباعتراف الجميع انها ليست الحل الأكثر فعالية، ولكن ليس لديها أي أرقام سحرية.
ويمكنك القيام بذلك دون تجاوز مشغل سفينة الفضاء عن طريق تحديد طريقة المقارنة جديد.
class Child
include Comparable
def compare_by_category(other)
return 0 if !category && !other.category
return 1 if !category
return -1 if !other.category
category.position <=> other.category.position
end
end
وطريقة sort
يمكن أن كتلة، لذلك يمكنك بعد ذلك النوع باستخدام هذه الطريقة الجديدة:
children.sort {|a,b| a.compare_by_category(b) }
والحل أبسط بالنسبة لي هو
def sorted_children(children)
children.sort_by { |child| child.position || -1}
end