2012-05-02 15 views
52

में मिली कुंजी का उपयोग करके ऑब्जेक्ट्स की सूची से मानचित्र बनाएं, मैं उत्कृष्ट Underscore.js लाइब्रेरी का उपयोग कर रहा हूं। मेरे पास एक विशिष्ट कार्य है जिसे मैं जावास्क्रिप्ट या jQuery का उपयोग करके ठीक कर सकता हूं लेकिन यह सोच रहा था कि अंडरस्कोर में कुछ प्रकार का अमूर्तता उपलब्ध नहीं है, जिसे मैं याद कर रहा था।Underscore.js: ऑब्जेक्ट

अनिवार्य रूप से मैं बहुत की तरह एक वस्तु है -

var some_map = {"a": {id: "a", val: 55}, "b": {id: "b", val: 1}, "c": {id: "c", val: 45}}; 

मुझे पता है कि मैं _.groupBy(some_object_array, "id") उपयोग कर सकते हैं -

var some_object_array = [{id: "a", val: 55}, {id: "b", val: 1}, {id: "c", val: 45}]; 

मैं में इस परिवर्तित करना चाहते हैं। लेकिन यह एक मानचित्र देता है -

var some_grouped_map = {"a": [{id: "a", val: 55}], "b": [{id: "b", val: 1}], "c": [{id: "c", val: 45}]}; 

ध्यान दें कि ऐसा करने के लिए विज्ञापन किया जाता है। लेकिन मैं ऑब्जेक्ट्स पर फिर से घुसपैठ किए बिना some_map प्राप्त करने की उम्मीद कर रहा था।

किसी भी मदद की सराहना की।

उत्तर

80

Underscore.js के बाद से FWIW अब आप अपने मामले के लिए उपयोग कर सकते हैं _.object()

var some_map = _.object(_.map(some_object_array, function(item) { 
    return [item.id, item] 
})); 
+7

ऑब्जेक्ट्स पर मैपिंग * इतना * उपयोगी है कि मैं हमेशा 'mapo = _.compose (_। Object, _.map) को परिभाषित करता हूं; ' –

+0

ऐसा लगता है कि' _.object() 'हटा दिया गया है। क्या यह अभी भी अंडरस्कोर में उपलब्ध है? –

+1

अगर मैं गलत हूं, तो मुझे सही करें, लेकिन मुझे लगता है कि लॉनाश के साथ आप एकल '_.transform' फ़ंक्शन का भी उपयोग कर सकते हैं। – emkman

12

मुझे नहीं लगता कि आपकी जरूरतों के लिए समूह से कुछ करीब है। यहां तक ​​कि अगर वहाँ था, यह एक साधारण से बेहतर कर नहीं होगा:

var some_map = {}; 
_.each(some_object_array, function(val) { 
    some_map[val.id] = val; 
}); 
+0

ठीक है, thats क्या मैं अंत में किया था। लेकिन यह उत्सुक था कि ऐसा करने का एक बेहतर तरीका था। – Chantz

+0

+1 क्योंकि मुझे यह दृष्टिकोण '_.object (_। नक्शा (...)) ' –

+0

' से अधिक सरल लगता है, यह' _.chain (डेटा) .map ((val) => [val।) के लिए चेनिंग है। आईडी, वैल]) ऑब्जेक्ट()। वैल्यू() ' – svarog

30

भी इस विधि

_.reduce(data, function (o, item) { o[item.key] = item.value; return o }, {}) 

कौन सा भीतरी समारोह में दो बयानों के साथ एक बयान है नहीं है।

+1

आपको कम उपयोग नहीं करना चाहिए क्योंकि इसका उपयोग विभिन्न उद्देश्यों के लिए किया जाता है (मानों की सूची को एक मूल्य में नीचे फोल्ड करें), मूल रूप से यह एक हैक है, जो लीड अपने कोड पढ़ने वाले अन्य देवताओं के लिए बहुत भ्रम के लिए ... – user2846569

+5

@ user2846569 यह एक वस्तु में एक सूची को उबालता है। 'कम करें' का पूरी तरह से आवेदन। –

+0

@OttoAllmendinger हालांकि, निर्दिष्ट कमी ऑपरेशन हेट्रेग्रेनस तर्क का उपयोग करता है, जो अपरंपरागत है। एक पारंपरिक कमी समारोह में, आप एक ही प्रकार के होने के लिए अपने 'ए' और' बी' (यहां 'ओ' और 'आइटम') चाहते हैं। वास्तव में, दृढ़ता से टाइप की गई भाषाएं यहां दिखाए गए इस तरह के कमी समारोह की अनुमति नहीं देगी। – Milosz

40

, आप indexBy समारोह का उपयोग करना चाहिए:

var some_object_array = [{id: "a", val: 55}, {id: "b", val: 1}, {id: "c", val: 45}]; 

var some_grouped_map = _.indexBy(some_object_array, 'id'); 
+0

के नवीनतम संस्करण में हटाया नहीं गया है – user2846569

+0

मामले के लिए सबसे उपयुक्त उत्तर सहमत है, यह स्वीकार्य उत्तर होना चाहिए। –

+0

यह उत्तर है। –

3

मैं इस मामले आप पुनरावृति की जरूरत नहीं है सरणी। map नहीं, reduce नहीं, transform नहीं। आप सभी की जरूरत पुराने pluck

_.object(_.pluck(some_object_array, 'id'), some_object_array); 
2

ES6 के लिए है, यह

var some_map = _.chain(some_object_array) 
       .map(item => [item.id, item]) 
       .object() 
       .value() 
संबंधित मुद्दे