كيف يمكنني الفرز حسب شروط متعددة بأوامر مختلفة؟

StackOverflow https://stackoverflow.com/questions/73032

  •  09-06-2019
  •  | 
  •  

سؤال

أرغب حقًا في التعامل مع هذا دون الحاجة إلى الترقيع القرد ولكني لم أتمكن من العثور على خيار آخر حتى الآن.

لدي مصفوفة (في روبي) أحتاج إلى فرزها حسب شروط متعددة.أعرف كيفية استخدام طريقة الفرز ولقد استخدمت الحيلة في الفرز باستخدام مجموعة من الخيارات للفرز حسب شروط متعددة.ومع ذلك، في هذه الحالة أحتاج إلى الشرط الأول للفرز تصاعديًا والثاني للفرز تنازليًا.على سبيل المثال:

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"]]

لقد كنت أستخدم وصفة جلين منذ فترة طويلة.تعبت من نسخ التعليمات البرمجية من مشروع إلى آخر مرارا وتكرارا، لقد قررت أن أجعلها جوهرة:

http://github.com/dadooda/invert

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