كيف يمكنني الفرز حسب شروط متعددة بأوامر مختلفة؟
سؤال
أرغب حقًا في التعامل مع هذا دون الحاجة إلى الترقيع القرد ولكني لم أتمكن من العثور على خيار آخر حتى الآن.
لدي مصفوفة (في روبي) أحتاج إلى فرزها حسب شروط متعددة.أعرف كيفية استخدام طريقة الفرز ولقد استخدمت الحيلة في الفرز باستخدام مجموعة من الخيارات للفرز حسب شروط متعددة.ومع ذلك، في هذه الحالة أحتاج إلى الشرط الأول للفرز تصاعديًا والثاني للفرز تنازليًا.على سبيل المثال:
ordered_list = [[1, 2], [1, 1], [2, 1]]
أي اقتراحات؟
يحرر:أدركت للتو أنني يجب أن أذكر أنه لا يمكنني بسهولة مقارنة القيمتين الأولى والثانية (أنا أعمل بالفعل مع سمات الكائن هنا).لذا، للحصول على مثال بسيط، يبدو الأمر أشبه بما يلي:
ordered_list = [[1, "b"], [1, "a"], [2, "a"]]
المحلول
ماذا عن:
ordered_list = [[1, "b"], [1, "a"], [2, "a"]]
ordered_list.sort! do |a,b|
[a[0],b[1]] <=> [b[0], a[1]]
end
نصائح أخرى
كنت أعاني من كابوس في بعض الأحيان أثناء محاولتي معرفة كيفية عكس فرز سمة معينة ولكن عادةً ما أقوم بفرز السمتين الأخريين.مجرد ملاحظة حول الفرز لأولئك الذين يأتون بعد هذا ويتم الخلط بينهم من قبل | a ، b | بناء الجملة.لا يمكنك استخدام {|a,b| a.blah <=> b.blah}
نمط الكتلة مع sort_by!
أو sort_by
.يجب استخدامه مع sort!
أو sort
.وأيضاً كما أشرنا سابقاً من خلال تبادل الملصقات الأخرى a
و b
عبر عامل المقارنة <=>
لعكس ترتيب الفرز.مثله:
للفرز حسب بلاه والزحف بشكل طبيعي، ولكن الفرز حسب بلو بترتيب عكسي، قم بما يلي:
something.sort!{|a,b| [a.blah, b.bleu, a.craw] <=> [b.blah, a.bleu, b.craw]}
ومن الممكن أيضًا استخدام -
التوقيع مع sort_by
أو sort_by!
لإجراء فرز عكسي على الأرقام (بقدر ما أعلم أنه يعمل فقط على الأرقام، لذا لا تحاول ذلك باستخدام السلاسل لأنه مجرد أخطاء ويقتل الصفحة).
يفترض a.craw
هو عدد صحيح.على سبيل المثال:
something.sort_by!{|a| [a.blah, -a.craw, a.bleu]}
كان لدي نفس المشكلة الأساسية، وحلها عن طريق إضافة هذا:
class Inverter
attr_reader :o
def initialize(o)
@o = o
end
def <=>(other)
if @o.is && other.o.is
-(@o <=> other.o)
else
@o <=> other.o
end
end
end
هذا عبارة عن غلاف يقوم ببساطة بعكس الدالة <=>، والتي تتيح لك بعد ذلك القيام بأشياء مثل هذا:
your_objects.sort_by {|y| [y.prop1,Inverter.new(y.prop2)]}
Enumerable#multisort
هو حل عام يمكن تطبيقه على صفائف اي حجم, ، وليس فقط أولئك الذين لديهم عنصرين.الوسيطات هي قيم منطقية تشير إلى ما إذا كان يجب فرز حقل معين تصاعديًا أو تنازليًا (الاستخدام أدناه):
items = [
[3, "Britney"],
[1, "Corin"],
[2, "Cody"],
[5, "Adam"],
[1, "Sally"],
[2, "Zack"],
[5, "Betty"]
]
module Enumerable
def multisort(*args)
sort do |a, b|
i, res = -1, 0
res = a[i] <=> b[i] until !res.zero? or (i+=1) == a.size
args[i] == false ? -res : res
end
end
end
items.multisort(true, false)
# => [[1, "Sally"], [1, "Corin"], [2, "Zack"], [2, "Cody"], [3, "Britney"], [5, "Betty"], [5, "Adam"]]
items.multisort(false, true)
# => [[5, "Adam"], [5, "Betty"], [3, "Britney"], [2, "Cody"], [2, "Zack"], [1, "Corin"], [1, "Sally"]]
لقد كنت أستخدم وصفة جلين منذ فترة طويلة.تعبت من نسخ التعليمات البرمجية من مشروع إلى آخر مرارا وتكرارا، لقد قررت أن أجعلها جوهرة: