ऑब्जेक्ट विशेषता द्वारा रूबी में वस्तुओं की एक सरणी को छाँटना?


128

मेरे पास रूबी ऑन रेल्स में वस्तुओं की एक सरणी है। मैं ऑब्जेक्ट की एक विशेषता द्वारा सरणी को सॉर्ट करना चाहता हूं। क्या यह संभव है?

जवाबों:


222

मैं इसके बजाय Sort_by का उपयोग करने की सलाह देता हूं:

objects.sort_by {|obj| obj.attribute}

खासकर अगर विशेषता की गणना की जा सकती है।

या अधिक संक्षिप्त दृष्टिकोण:

objects.sort_by(&:attribute)

81
या शॉर्टहैंड संस्करण:objects.sort_by(&:attribute)
निकोला

3
इससे भी अधिक छोटी
वस्तु। sort_by

1
यदि आपको अपरकेस और लोअरकेस अक्षरों को अलग-अलग क्रमबद्ध करने में समस्या है, तो आप उपयोग कर सकते हैंobjects.sort_by { |obj| obj.attribute.downcase }
कैंपसटरन

1
किसी भी विचार कैसे इस के साथ तुलना sort!(जैसे गति, आदि)?
जोशुआ पिंटर


35

हां, इसका उपयोग Array#sort!करना आसान है।

myarray.sort! { |a, b|  a.attribute <=> b.attribute }

Thnx दोस्त लेकिन यह मेरे लिए काम नहीं किया मैं वस्तुओं की एक सरणी है। जिसमें वस्तु का एक गुण create_at होता है। मैं इसे इस क्षेत्र के साथ क्रमबद्ध करना चाहता हूं। तो मैंने @ comm_bytes.sort किया! {(ए, बी | अ।

4
क्या @created_at विशेषता तक पहुंचने के लिए एक बनाया_ तरीका है? @Created_at किस तरह की वस्तु है? क्या यह परिभाषित करता है <=>? किस तरह की त्रुटियां हो रही हैं? आदि, विज्ञापन, nauseum दूसरे शब्दों में, हमें "लेकिन मेरे लिए कोई भाग्य नहीं" से अधिक विस्तार की आवश्यकता है।
प्राचीर

यह काम करता है अगर आप myarray = myarray.sort {...} बिना "!"
डोरुसीडियन

@ डोरू हां, वह भी काम करता है, लेकिन आप ऐसा क्यों करेंगे? यह कम प्रत्यक्ष और कम कुशल है। sortयदि आप मूल को संरक्षित करना चाहते हैं और परिणाम को किसी भिन्न ऑब्जेक्ट पर असाइन करना चाहते हैं, तो उपयोग करें ; अन्यथा,, यथा-स्थान भिन्न रूप का उपयोग sort!। वास्तव में, मूल वस्तु की नकल करने के बाद, आंतरिक रूप से sortकॉल करता है sort!
कोनराड रूडोल्फ

1
@ डोरू कोड में कहीं और त्रुटि हो सकती है, मैं आपको 100% गारंटी दे सकता हूं कि sort!बस ठीक काम करेगा, और हमेशा (!) जैसा आपने लिखा है वैसा ही करें।
कोनराड रुडोल्फ

27

आरोही क्रम :

objects_array.sort! { |a, b|  a.attribute <=> b.attribute }

या

objects_array.sort_by{ |obj| obj.attribute }

घटते क्रम में :

objects_array.sort! { |a, b|  b.attribute <=> a.attribute }

या

objects_array.sort_by{ |obj| obj.attribute }.reverse

20

यदि आपको दो विशेषताओं के आधार पर छंटनी की आवश्यकता होती है, जहां पहले एक और अधिक महत्वपूर्ण है तो दूसरा (मतलब दूसरी दलील को ध्यान में रखते हुए यदि पहले तर्क समान हैं), तो आप ऐसा कर सकते हैं

myarray.sort{ |a,b| (a.attr1 == b.attr1) ? a.attr2 <=> b.attr2 : a.attr1 <=> b.attr1 }

या सरणी के मामले में

myarray.sort{ |a,b| (a[0] == b[0]) ? a[1] <=> b[1] : a[0] <=> b[0] }

14

आप <=> विधि को ओवरराइड करके किसी भी वर्ग को क्रमबद्ध कर सकते हैं:

class Person

  attr_accessor :first_name, :last_name

  def initialize(first_name, last_name)
    @first_name = first_name
    @last_name = last_name
  end

  def <=>(other)
    @last_name + @first_name <=> other.last_name + other.first_name
  end

end

अब last_name पर व्यक्तिगत वस्तुओं की एक सरणी छंटनी होगी।

ar = [Person.new("Eric", "Cunningham"), Person.new("Homer", "Allen")]

puts ar  # => [ "Eric Cunningham", "Homer Allen"]  (Person objects!)

ar.sort!

puts ar  # => [ "Homer Allen", "Eric Cunningham" ]

10

जैसा कि ऊपर पोस्ट किया गया है, एरियर # सॉर्ट अच्छा काम करता है:

myarray.sort! { |a, b|  a.attribute <=> b.attribute }

लेकिन, आपको यह सुनिश्चित करने की आवश्यकता है कि <=>ऑपरेटर उस विशेषता के लिए कार्यान्वित किया गया है। यदि यह रूबी मूल डेटा प्रकार है, तो यह कोई समस्या नहीं है। अन्यथा, आप अपने स्वयं के कार्यान्वयन को लिखते हैं जो -1 लौटाता है अगर <b, 0 यदि वे समान हैं, और 1 यदि a> b है।


10

अधिक सुरुचिपूर्ण objects.sort_by(&:attribute), आप .reverseऑर्डर को स्विच करने की आवश्यकता होने पर जोड़ सकते हैं ।



-2
@model_name.sort! { |a,b| a.attribute <=> b.attribute }

2
2009 में बहुत सारे समान जवाब पोस्ट किए गए हैं। किसी और को जोड़ने की आवश्यकता नहीं है।
अंतरजाल

2
sortजब आप ऐसी वस्तुओं को छाँट रहे हों, जिनका उपयोग सीधे नहीं किया जा सकता है। यदि आपको उपयोग की विशेषताओं को प्राप्त करना है या उपयोग की तुलना करने के लिए मूल्य प्राप्त करने के लिए एक संगणना करना है sort_by। यह ज्यादा तेज होगा।
द टिन मैन
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.