2012-03-20 15 views
19

इस तरह की एक सरणी के साथ:मैं कॉफ़ीस्क्रिप्ट के साथ एक ऐरे को कैसे सॉर्ट करूं?

users.sort (a,b) -> 
    return if a.lname.toUpperCase() >= b.lname.toUpperCase() then 1 else -1 

मैं इस तरह एक समारोह उपयोग करने की कोशिश:

sortBy = (field, reverse, primer) -> 
    key = (x) -> 
     return if primer? then primer x[field] else x[field] 
    return (a,b) -> 
     A = key a 
     B = key b 
     return (A < B ? -1 : (A > B ? 1 : 0)) * [1,-1][+!!reverse] 

users = [ 
    { id: 1, fname: 'Fred', lname: 'Flinstone', state: 'CA' }, 
    { id: 2, fname: 'George', lname: 'Winston', state: 'FL' }, 
    { id: 3, fname: 'Luke', lname: 'Skywalker', state: 'CA' } 
] 

और आप coffeescript साथ अंतिम नाम से क्रमबद्ध करना चाहते हैं, तो आप ऐसा कर सकते हैं

जिसे इस तरह से बुलाया गया था:

users.sort sortBy "lname", false, (a) -> 
    return a.toUpperCase() 

लेकिन यह सरणी को ठीक तरह से सॉर्ट नहीं किया गया।

क्या 1 से अधिक फ़ील्ड द्वारा सॉर्ट करने का कोई तरीका है, यानी पहले राज्य द्वारा क्रमबद्ध करें, और फिर अंतिम नाम से? मैं ऊपर "sortby" फ़ंक्शन पर सुधार करने की उम्मीद कर रहा था और कम से कम 2 फ़ील्ड द्वारा क्रमबद्ध करने की क्षमता जोड़ सकता था।

+2

बात किस तरह की "बेहतर" है कि तुलना में हो सकता है पाया के आधार पर? (असल में मैं स्थिर रखने में मदद के लिए '<=' और '' '' '' 'का उपयोग नहीं करता।) – Pointy

+3

यह JSON नहीं है। –

+0

आप वहां टर्नरी ऑपरेटर का उपयोग कर सकते हैं: 'a.lname.toUpperCase()> b.lname.toUpperCase() वापस करें? 1: -1' –

उत्तर

20

एक सरल तरीका नहीं है। बस अपने सामान्यीकृत छँटाई समारोह का फिर से उपयोग, और || का उपयोग कर उन्हें श्रेणीबद्ध:

sortBy = (key, a, b, r) -> 
    r = if r then 1 else -1 
    return -1*r if a[key] > b[key] 
    return +1*r if a[key] < b[key] 
    return 0 

users.sort (a,b) -> 
    sortBy('id', a, b, true) or 
    sortBy('lname', a, b) or 
    sortBy('fname', a, b) 

कार्य सस्ता कर रहे हैं। तब आप उस के लिए एक अमूर्त का निर्माण कर सकते हैं:

sortByMultiple = (a, b, keys) -> 
    return r if (r = sortBy key, a, b) for key in keys 
    return 0 

users.sort (a,b) -> sortByMultiple a, b, ['id', 'lname', 'fname'] 

लेकिन तब आप इनमें से प्रत्येक पर आदेश या अन्य पैरामीटर निर्धारित करने की क्षमता खो देते हैं।

+0

हैं जो वाकई चालाक हैं। मैं समझने की कोशिश कर रहा हूं कि 'या' कार्यों को चेन करने के साथ कैसे काम करता है। क्या ऐसा इसलिए है क्योंकि यह केवल अगले क्रम में चलता है यदि पिछले रिटर्न '0' पर काम करता है? या शायद इसे रखने का एक और तरीका यह है कि जब तक पहली कुंजी संतुष्ट न हो जाए तब तक यह क्रमबद्ध रहेगा (यानी '0') और फिर अगले स्थान पर जाएं? – jiy

+0

परीक्षण की जांच की गई जांच के साथ या - महान काम करता है! मिश्रण को फेंकना मिश्रण में बहुमत सफल नहीं था हालांकि, कुछ भी सही ढंग से हल नहीं किया गया था। एक बहुत उपयोगी उत्तर के लिए धन्यवाद! – jiy

+0

@jiy हाँ, यह बहुत अधिक है। जारी रखें जब तक कि मानदंड में से कोई एक गैर-शून्य मान देता है। –

15

वैकल्पिक रूप से, आप का उपयोग कर विचार करना चाह सकते Underscore के sortBy आप इसे अपने आप को लागू करने के लिए की जरूरत नहीं है, इसलिए है कि:

_(users).sortBy (u) -> [u.state, u.lname.toUpperCase()] 
+0

धन्यवाद! यह बेहद आशाजनक दिखता है। वास्तव में मैं – jiy

+0

के लिए क्या देख रहा था आपके उत्तर में लिंक अब मौजूद नहीं हैं http://underscorejs.org/ और http://underscorejs.org/#sortBy नए लिंक –

3

यह ऐसा कुछ है जो मैंने सोचा था कि lodash का उपयोग करते समय डिफ़ॉल्ट रूप से लागू किया गया था, लेकिन ऐसा नहीं है।

तो हम यहां हैं!

sortByLowercase: (collection, key) -> 
    collection.sort (a, b) -> 
     [av, bv] = [a[key], b[key]] 
     [av, bv] = [av.toLowerCase(), bv.toLowerCase()] 
     if av >= bv then 1 else if av <= bv then -1 else 0 

sortByLowercase(users,'lname') 

एक अधिक सामान्य उदाहरण मैं here

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