2012-05-16 6 views
12

मैं निम्नलिखित उपयोग स्थिति के लिए अपने ही छंटाई एल्गोरिथ्म लेखन से बचने के लिए कोशिश कर रहा हूँ में रूपांतरित किए बिना जावास्क्रिप्ट में वस्तुओं का संग्रह सॉर्ट करने के लिए कैसे:यह एक सरणी

    :

    avatars = {}; 
    avatars[102] = {userInfo: {buddy_name: 'Avatar102', is_online: 1}}; 
    avatars[100] = {userInfo: {buddy_name: 'Avatar100', is_online: 1}}; 
    avatars[101] = {userInfo: {buddy_name: 'Avatar101', is_online: 1}}; 
    
    console.log(_.keys(avatars)); 
    avatars = _.sortBy(avatars, function(avatar) {return avatar.userInfo.buddy_name.toLowerCase();}); 
    console.log(_.keys(avatars)); 
    

    यहाँ सांत्वना उत्पादन है

  • [ "102", "100", "101"]
  • [ "0", "1", "2"]

आप देख सकते हैं, undes साथ कोर की तरह मैं मुख्य डेटा खो रहा हूँ। यह संरचना बहुत बड़ी हो सकती है, इसलिए मैं एक सरणी में परिवर्तित करने और फिर संग्रह में वापस आने जैसी चीजों से बचने की कोशिश कर रहा हूं। क्या मेरे स्वयं के सॉर्ट फ़ंक्शन को घुमाने के बिना ऐसा करने का कोई तरीका है?

+2

अवतार एक शब्दकोश है और इसकी प्रकृति से अनुरक्षित है। तो, आपको वास्तव में क्या चाहिए? क्रम में अवतारों को फिर से चलाने की क्षमता? विस्तृत प्रतिक्रिया के लिए –

+0

http://jsfiddle.net/zL9GD/2/ –

उत्तर

26

आपका avatars, किसी सरणी नहीं है यह सिर्फ एक वस्तु है:

avatars = {}; 

तो वहाँ है no defined order for its elements:

यांत्रिकी और गुण की गणना का क्रम (में कदम 6. a पहले एल्गोरिदम, दूसरे में चरण 7. ए) निर्दिष्ट नहीं है।

और 15.2.3.7 (और 15.2.3.14):

एक कार्यान्वयन के लिए गणन की एक विशेष क्रम को परिभाषित करता है, तो के लिए में बयान, कि एक ही गणना क्रम चरण 3 में सूची तत्वों ऑर्डर करने के लिए इस्तेमाल किया जाना चाहिए इस एल्गोरिदम का।

तुम भी section 8.6 पूछें कि ऐसी कोई वस्तु में गुणों का आदेश के बारे में कोई उल्लेख नहीं है को देखने के लिए कर सकते हैं। ऑब्जेक्ट गुणों को ऑर्डर करने की एकमात्र आवश्यकता यह है कि यदि कार्यान्वयन कहीं भी किसी ऑर्डर को परिभाषित करता है तो उसे हर जगह उसी ऑर्डरिंग का उपयोग करना होगा, लेकिन यदि है तो यह बड़ा है। अधिकतर कार्यान्वयन शायद किसी ऑब्जेक्ट की चाबियों के लिए सम्मिलन आदेश का उपयोग करते हैं, लेकिन मुझे ऐसा कुछ भी नहीं मिल रहा है जिसके लिए उन्हें आवश्यकता होती है (यदि कोई किसी ऑब्जेक्ट की चाबियों के किसी भी विशेष क्रम को परिभाषित करने वाले चश्मा में कुछ भी इंगित कर सकता है तो मैं एक टिप्पणी की सराहना करता हूं)।

कहा, अंडरस्कोर के sortBy मूल रूप से एक Schwartzian Transform खोलने में Schwartzian ज्ञापन रैपर रूपांतरण एक मानक जावास्क्रिप्ट sort और अंडरस्कोर के pluck के साथ संयुक्त है, pluck एक सरणी देता है इसलिए sortBy भी एक सरणी देता है। इसलिए, आपका अंतिम _.keys(avatars) कॉल वास्तव में एक सरणी पर _.keys पर कॉल कर रहा है; एक सरणी की चाबियाँ (AKA संख्यात्मक गुण) सरणी के सूचकांक हैं और वे निरंतर पूर्णांक शून्य से शुरू होते हैं।

आप गलत डेटा संरचना का उपयोग कर रहे हैं। यदि आपको स्पैस सरणी की आवश्यकता है लेकिन इसे सरणी की तरह हेरफेर करने की आवश्यकता है (यानी।तरह यह), तो आप वस्तुओं के अंदर अनुक्रमित रख दिया और एक सामान्य सरणी का उपयोग करें और pluckkeys के बजाय चाहिए:

var avatars = [ 
    {idx: 102, userInfo: {buddy_name: 'Avatar102', is_online: 1}}, 
    {idx: 100, userInfo: {buddy_name: 'Avatar100', is_online: 1}}, 
    {idx: 101, userInfo: {buddy_name: 'Avatar101', is_online: 1}} 
]; 
console.log(_(avatars).pluck('idx')); 
avatars = _(avatars).sortBy(function(avatar) { 
    return avatar.userInfo.buddy_name.toLowerCase(); 
}); 
console.log(_(avatars).pluck('idx')); 

डेमो: http://jsfiddle.net/ambiguous/UCWL2/

आप भी idx द्वारा त्वरित पहुँच की जरूरत है तो आप सेट कर सकते हैं

var avatars_by_idx = { }; 
for(var i = 0; i < avatars.length; ++i) 
    avatars_by_idx[avatars[i].idx] = avatars[i]; 

फिर avatars_by_idx सीधी पहुँच आप देख रहे हैं प्रदान करता है: प्रत्यक्ष idx पहुँच के लिए एक समानांतर वस्तु अप। बेशक, आपको avatars और avatars_by_idx सिंक्रनाइज़ करना होगा, लेकिन यदि आप किसी ऑब्जेक्ट के पीछे उन्हें छुपाते हैं तो यह बहुत मुश्किल नहीं है।

+0

धन्यवाद। दुर्भाग्य से मुझे आईडीएक्स का उपयोग करके अवतार संग्रह में "रिकॉर्ड्स" को तुरंत देखने में सक्षम होना चाहिए, इसलिए डेटा संरचना को बदलना एक विकल्प नहीं है। हो सकता है कि सॉर्टिंग के लिए उपयोग की जाने वाली एक नई सूची बनाना बेहतर होगा ... – Rosco

+0

@ रोस्को: यदि आप केवल कच्चे 'अवतार' डेटा के साथ काम कर रहे हैं तो मुख्य स्टोर के रूप में उपरोक्त 'अवतार' सरणी का उपयोग करें और रखें एक अलग ऑब्जेक्ट जो 'अवतार' सरणी में 'idx' ऑब्जेक्ट्स को ऑब्जेक्ट करता है। यह अतिरिक्त 'avatars_by_idx' ऑब्जेक्ट डेटाबेस में एक इंडेक्स के समान उद्देश्य प्रदान करेगा। –

+0

हम्म - मैं विपरीत सोच रहा था - डेटा स्टोर idx पर की गई ऑब्जेक्ट्स का संग्रह होगा, और क्रमबद्ध सरणी में केवल buddy_name के आधार पर आदेश दिया गया idx होगा। मैं यह उल्लेख करना भूल गया कि शुरुआतीकरण के बाद संरचना में नए अवतार जोड़े गए हैं ... – Rosco