2013-02-11 14 views
10

मैं products की एक गैलरी प्रदर्शित करना चाहता हूं, जहां मैं उन उत्पादों को शामिल करता हूं जो बिक्री के लिए हैं और बिक्री के लिए नहीं हैं। केवल मैं products चाहता हूं जो सूची के सामने दिखाई देने वाली बिक्री के लिए हैं और वस्तुओं के लिए बिक्री के लिए नहीं हैं सूची के अंत में दिखाई देंगे।क्या किसी ऑब्जेक्ट की व्यक्तिगत ऑब्जेक्ट की प्रतिक्रिया के आधार पर ऑब्जेक्ट्स की सूची सॉर्ट करना संभव है?

available_products = [] 
sold_products = [] 
@products.each do |product| 
    if product.on_sale? 
    available_products << product 
    else 
    sold_products << product 
    end 
end 

:

मुझे यह पूरा करने के लिए एक आसान तरीका है दो सूचियों बनाने के लिए, तो उन्हें (? On_sale वस्तुओं में से एक सूची और on_sale नहीं वस्तुओं में से एक सूची) विलय है। । । लेकिन मेरे मौजूदा ऐप की संरचना के लिए, इसके लिए मेरे कोड में अजीबता के कारण अत्यधिक मात्रा में रिफैक्टरिंग की आवश्यकता होगी (मैं अपना पेजिनेशन खो देता हूं, और मैं रिफैक्टर नहीं करता)। यह आसान होगा अगर मेरे product मॉडल की विधि on_sale? द्वारा ऑब्जेक्ट की मौजूदा सूची को सॉर्ट करने का कोई तरीका था जो एक बूलियन मान देता है।

क्या मौजूदा सूची के माध्यम से और अधिक स्पष्ट रूप से पुन: प्रयास करना संभव है और इसे रेल में इस वास्तविक या गलत मूल्य से सॉर्ट करना संभव है? मैं केवल इसलिए पूछता हूं क्योंकि मुझे इस ढांचे/भाषा (रूबी) के अंदर छिपे हुए बारे में पता नहीं है और मैं जानना चाहता हूं कि वे मेरे सामने काम कर चुके हैं या नहीं।

उत्तर

11

निश्चित रूप से। आदर्श रूप में हम sort_by! का उपयोग कर कुछ इस तरह करते हैं:

@products.sort_by! {|product| product.on_sale?} 

या snazzier

@products.sort_by!(&:on_sale?) 

लेकिन दुर्भाग्य से, <=> (Why doesn't sort or the spaceship (flying saucer) operator (<=>) work on booleans in Ruby? देखें) बूलियन्स लिए काम नहीं करता और sort_by बूलियन लिए काम नहीं करता मूल्यों, इसलिए हम इस चाल का उपयोग करने की जरूरत है (धन्यवाद rohit89!)

@products.sort_by! {|product| product.on_sale? ? 0 : 1} 

यदि आप प्रशंसक प्राप्त करना चाहते हैं, तो sort विधि एक ब्लॉक लेती है, और उस ब्लॉक के अंदर आप टाइप रूपांतरण और एकाधिक कुंजी सहित, जो भी तर्क पसंद करते हैं उसका उपयोग कर सकते हैं।

@products.sort! do |a,b| 
    a_value = a.on_sale? ? 0 : 1 
    b_value = b.on_sale? ? 0 : 1 
    a_value <=> b_value 
end 

या इस:

@products.sort! do |a,b| 
    b.on_sale?.to_s <=> a.on_sale?.to_s 
end 

(पहले एक है क्योंकि आप "true" मूल्यों "false" से पहले आना चाहता हूँ ख डाल) या आप एक माध्यमिक तरह अगर:

कुछ इस तरह की कोशिश करो
@products.sort! do |a,b| 
    if a.on_sale? != b.on_sale? 
    b.on_sale?.to_s <=> a.on_sale?.to_s 
    else 
    a.name <=> b.name 
    end 
end 

ध्यान दें कि sort एक रिटर्न देता है ईवी संग्रह, जो आमतौर पर एक क्लीनर, कम त्रुटि-प्रवण समाधान होता है, लेकिन sort! मूल संग्रह की सामग्री को संशोधित करता है, जिसे आपने कहा था।

+0

महान लग रहा है! लेकिन मुझे इसके विशिष्ट कोड के साथ समस्याएं आ रही हैं, शायद आप इसके साथ मेरी मदद कर सकते हैं। यदि मैं एक-लाइनर का उपयोग करता हूं तो मुझे निम्न त्रुटि 'गलत विफलता के साथ गलत भाषा की तुलना' मिलती है, और यदि मैंने आपके द्वारा उल्लिखित पहले कोड का उपयोग किया है, तो मुझे [MyModule] :: [MyModule] :: उत्पाद के साथ उत्पाद की तुलना मिलती है :: उत्पाद विफल '। यकीन नहीं है कि यह क्यों विफल होगा। – Ecnalyr

+0

कुछ नोट्स: 1) जब भी संभव हो, 'हमेशा' sort'by' पर 'sort_by' का उपयोग करना चाहिए (अधिक घोषणात्मक, अधिक संक्षिप्त, अधिक कुशल)। ऊपर दिखाए गए सभी स्निपेट में इसका उपयोग करना संभव है। 2) क्या मैं गैर-विनाशकारी 'संख्यात्मक # sort_by' से लिंक करना बेहतर कर सकता हूं, जब भी संभव हो, इन-प्लेस अपडेट से बचा जाना चाहिए। 3) '@ product.sort_by (&: on_sale?)'। – tokland

+0

लगता है कि '<=> 'बूलियन के लिए सही काम नहीं करता है (रूबी-1.9.3-पी 327 में)। इसे में अब देख रहे हैं, हाँ ... http://grosser.it/2010/07/30/ruby-true-false-comparison-with/ पिछले संस्करण – AlexChaffee

4

@products.sort_by {|product| product.on_sale? ? 0 : 1}

यह मैं क्या किया था जब मैं बूलियन्स के आधार पर सॉर्ट करने के लिए था।

4

कोई ज़रूरत नहीं सॉर्ट करने के लिए:

products_grouped = @products.partition(&:on_sale?).flatten(1) 
0

आरोही और उतरते अंतर बदलते द्वारा किया जा सकता "गलत" और "सही"

Products.sort_by {|product| product.on_sale? == true ? "false" : "true" } 
संबंधित मुद्दे