2012-03-15 12 views
6

मैं की एक सूची है में ग्रूवी में एक सूची छँटाई, मान लीजिए कि [बिल्ली, कुत्ता, गाय, घोड़े], कि मैं चाहता हूँ निम्नलिखित तरीके से क्रमबद्ध करनाएक असामान्य तरीका

  • अगर बिल्ली में है सूची में पहली बार
  • यदि गाय सूची में है तो इसे दूसरे
  • पर जाना चाहिए शेष तत्व वर्णमाला क्रम में बाद में आना चाहिए।

कोई सुझाव यह कैसे ग्रोवी में किया जा सकता है?

+1

यदि गाय सूची में है और बिल्ली नहीं है, तो क्या गाय को अभी भी दूसरी जगह में होना चाहिए? क्या होगा अगर सूची सिर्फ '[गाय'] है? – ataylor

+0

नहीं तो गाय पहले होना चाहिए। – bladet

उत्तर

7

टिम का जवाब बहुत चालाक है। मैं सूची संचालन का उपयोग करने के लिए व्यक्तिगत रूप से अधिक प्रशंसक हूं क्योंकि जो कोड उत्पन्न करता है वह पढ़ने के लिए थोड़ा आसान है।

def highPriority = [ 'Cat', 'Cow' ] 

def list = [ 'Armadillo', 'Dog', 'Cow', 'Zebra', 'Horse', 'Cow', 'Cat' ] 

def remainder = (list - highPriority).sort() 

list.retainAll(highPriority) 

list.sort{ highPriority.indexOf(it) } + remainder 

इससे आपको दो बार गाय मिलेगा। यदि आप डुप्लिकेट नहीं चाहते हैं, तो अंतरण का उपयोग करना काफी सरल है।

def highPriority = [ 'Cat', 'Cow' ] 

def list = [ 'Armadillo', 'Dog', 'Cow', 'Zebra', 'Horse', 'Cow', 'Cat' ] 

list.intersect(highPriority).sort{ highPriority.indexOf(it) } + (list - highPriority).sort() 
+0

+1 अच्छा विकल्प :-) –

+0

मैं आपके साथ टॉमस से सहमत हूं। चूंकि मैं आपके समाधान का पालन करने के लिए बहुत आसान हूं, मेरे समाधान का पालन करना मेरे लिए आसान है। धन्यवाद। – bladet

+0

@ टॉमस: उत्कृष्ट उत्तर के लिए +1! –

6

यह करना चाहिए:

// Define our input list 
def list = [ 'Armadillo', 'Cat', 'Dog', 'Cow', 'Zebra', 'Horse', 'Cow' ] 

// Define a closure that will do the sorting 
def sorter = { String a, String b, List prefixes=[ 'Cat', 'Cow' ] -> 
    // Get the index into order for a and b 
    // if not found, set to being Integer.MAX_VALUE 
    def (aidx,bidx) = [a,b].collect { prefixes.indexOf it }.collect { 
    it == -1 ? Integer.MAX_VALUE : it 
    } 
    // Compare the two indexes. 
    // If they are the same, compare alphabetically 
    aidx <=> bidx ?: a <=> b 
} 

// Create a new list by sorting using our closure 
def sorted = list.sort false, sorter 

// Print it out 
println sorted 

कि प्रिंट:

[Cat, Cow, Cow, Armadillo, Dog, Horse, Zebra] 

मैं टिप्पणी की है यह कोशिश करते हैं और हर कदम लेता है समझाने के लिए। sorter बंद पर एक वैकल्पिक पैरामीटर के रूप में डिफ़ॉल्ट उपसर्ग आइटम को जोड़ कर, इसका मतलब है कि हम इस तरह सामान कर सकते हैं डिफ़ॉल्ट बदलने के लिए:

// Use Dog, Zebra, Cow as our prefix items 
def dzc = list.sort false, sorter.rcurry([ 'Dog', 'Zebra', 'Cow' ]) 
println dzc 

कौन सा फिर सूची प्रिंट के रूप में हल कर:

[Dog, Zebra, Cow, Cow, Armadillo, Cat, Horse] 
0

आप डुप्लिकेट तत्वों की जरूरत नहीं है, तो आप इस कोशिश कर सकते हैं:

def highPriority = [ 'Cat', 'Cow' ] 
def list = [ 'Armadillo', 'Dog', 'Cow', 'Zebra', 'Horse', 'Cat' ] 
highPriority + list.minus(highPriority).sort() 
+0

क्या होगा यदि बिल्ली सूची से गायब है? –

0

tomas' answer पर प्रेरित:

def highPriority = [ 'Cat', 'Cow' ] 
def list = [ 'Armadillo', 'Cat', 'Dog', 'Cow', 'Zebra', 'Horse', 'Cow' ] 

// Group animals by priority. 
def groups = list.groupBy { it in highPriority ? it : 'rest' } 
// High priority animals are sorted by priority and the rest alphabetically. 
def sorted = highPriority.collectMany { groups[it] } + groups['rest'].sort() 

assert sorted == ['Cat', 'Cow', 'Cow', 'Armadillo', 'Dog', 'Horse', 'Zebra'] 

groups चर [rest:[Armadillo, Dog, Zebra, Horse], Cat:[Cat], Cow:[Cow, Cow]] की तरह कुछ है।

एक और यकीनन कम प्रभावी है, समाधान हो सकता है:

def sorted = list.sort(false) { 
    def priority = highPriority.indexOf(it) 
    if (priority == -1) priority = highPriority.size() 
    // Sort first by priority and then by the value itself 
    "$priority$it" 
} 

यह अर्थ में कम मजबूत है कि यह "2Armadillo" तरह तार, "0Cat", आदि द्वारा सॉर्ट करता है, और यदि आप 9 है या काम नहीं करेगा अधिक उच्च प्राथमिकता वाले जानवर (क्योंकि "10Alpaca" < "9Eel"। यह अच्छा होगा अगर ग्रोवी ने Python's tuples जैसे कुछ तुलनीय टुपल प्रकार प्रदान किए, तो तुलनीय कुंजी के रूप में "$priority$it" लौटने की बजाय, कोई ट्यूपल (priority, it) लौटा सकता है।

1

यहाँ एक और विकल्प है कि मेरे पास सरल लगता है है:

// smaller values get sorted first 
def priority(animal) { 
    animal in ['Cat', 'Cow'] ? 0 : 1 
} 

def list = [ 'Armadillo', 'Cat', 'Dog', 'Cow', 'Zebra', 'Horse', 'Cow' ] 

def sorted = list.sort{ a, b -> priority(a) <=> priority(b) ?: a <=> b } 

assert sorted == ['Cat', 'Cow', 'Cow', 'Armadillo', 'Dog', 'Horse', 'Zebra'] 
+0

क्या होता है यदि आप अपनी प्राथमिकता सूची में बिल्ली से पहले गाय चाहते हैं? ;) –

+0

गाय प्राथमिकता 0, बिल्ली प्राथमिकता 1, बाकी सब कुछ प्राथमिकता दें 2. – ataylor

+0

ग्रोवी में: '[गाय: 0, बिल्ली: 1] .withDefault {2} [पशु]' :) – ataylor

0

यह सवाल बहुत पुराना है, लेकिन आज मैंने पाया ग्रूवी एक, बल्कि गैर-दस्तावेजी, OrderBy तुलनित्र कि इस मामले में इस्तेमाल किया जा सकता है:

def highPriority = ['Cow', 'Cat'] 
def list = ['Armadillo', 'Cat', 'Dog', 'Cow', 'Zebra', 'Horse', 'Cow'] 

def sorted = list.sort new OrderBy([{ -highPriority.indexOf(it) }, { it }]) 

assert sorted == ['Cat', 'Cow', 'Cow', 'Armadillo', 'Dog', 'Horse', 'Zebra'] 

OrderBy तुलनित्र पहले highPriority सूची में उनके सूचकांक का उपयोग कर जानवरों नकार (इसलिए कि जानवरों उच्च प्राथमिकता नहीं हैं तुलना (यानी सूचकांक -1) वापस करने के लिए ले जाया जाता है सूची में) और यदि इंडेक्स बराबर हैं तो यह उन्हें पहचान फ़ंक्शन {it} से तुलना करता है, जो जानवरों के तारों के रूप में होते हैं, उन्हें वर्णानुक्रम में टाइप करते हैं।

संबंधित मुद्दे