ऑब्जेक्ट के विशेषता मान द्वारा अनुक्रमित ऑब्जेक्ट सरणी को हैश मैप में कनवर्ट करें


305

उदाहरण

उपयोग का मामला वस्तुओं के एक सरणी को हैश मानचित्र में कुंजी के रूप में मूल्यांकन करने और उपयोग करने के लिए प्रदान की गई स्ट्रिंग या फ़ंक्शन के आधार पर एक हैश मानचित्र में एक वस्तु में परिवर्तित करने के लिए है। इसका उपयोग करने का एक सामान्य मामला वस्तुओं की एक सरणी को वस्तुओं के हैश मानचित्र में परिवर्तित कर रहा है।

कोड

ऑब्जेक्ट की विशेषता मान द्वारा अनुक्रमित हैश मैप में ऑब्जेक्ट्स की एक सरणी में परिवर्तित करने के लिए जावास्क्रिप्ट में एक छोटा सा स्निपेट है। आप गतिशील रूप से (रन समय) हैश मानचित्र की कुंजी का मूल्यांकन करने के लिए एक फ़ंक्शन प्रदान कर सकते हैं। आशा है कि यह भविष्य में किसी की मदद करेगा।

function isFunction(func) {
    return Object.prototype.toString.call(func) === '[object Function]';
}

/**
 * This function converts an array to hash map
 * @param {String | function} key describes the key to be evaluated in each object to use as key for hashmap
 * @returns Object
 * @Example 
 *      [{id:123, name:'naveen'}, {id:345, name:"kumar"}].toHashMap("id")
 *      Returns :- Object {123: Object, 345: Object}
 *
 *      [{id:123, name:'naveen'}, {id:345, name:"kumar"}].toHashMap(function(obj){return obj.id+1})
 *      Returns :- Object {124: Object, 346: Object}
 */
Array.prototype.toHashMap = function(key) {
    var _hashMap = {}, getKey = isFunction(key)?key: function(_obj){return _obj[key];};
    this.forEach(function (obj){
        _hashMap[getKey(obj)] = obj;
    });
    return _hashMap;
};

आप यहाँ गिस पा सकते हैं: हैशपॉइंट के लिए ऑब्जेक्ट्स का एवरेट


आप ऑब्जेक्ट के बजाय जावास्क्रिप्ट मैप का उपयोग कर सकते हैं। बाहर की जाँच करें stackoverflow.com/a/54246603/5042169
Jun711

जवाबों:


471

यह करने के लिए काफी तुच्छ है Array.prototype.reduce:

var arr = [
    { key: 'foo', val: 'bar' },
    { key: 'hello', val: 'world' }
];

var result = arr.reduce(function(map, obj) {
    map[obj.key] = obj.val;
    return map;
}, {});

console.log(result);
// { foo:'bar', hello:'world' }

नोट: Array.prototype.reduce() IE9 + है, इसलिए यदि आपको पुराने ब्राउज़रों का समर्थन करने की आवश्यकता है तो आपको इसे पॉलीफ़िल करना होगा।


47
result = arr.reduce((map, obj) => (map[obj.key] = obj.val, map), {});ES6 एक-लाइनर प्रशंसकों के लिए: D
Teodor Sandu

31
@ Mtz ES6 के लिए एक-लाइन प्रशंसक, नीचे mateuscb की प्रतिक्रिया बहुत छोटी और साफ है result = new Map(arr.map(obj => [obj.key, obj.val]));:। सबसे महत्वपूर्ण बात, यह स्पष्ट करता है कि एक नक्शा वापस किया जा रहा है।
रयान

2
@ रयानशिलिंगटन हम यहां एक उत्तर के संदर्भ में हैं, जो Array.prototype.reduceकि jmar777 द्वारा प्रस्तावित है। Mapवास्तव में कम है, लेकिन यह एक अलग बात है। मैं मूल इरादे के अनुरूप था। याद रखें कि यह एक मंच नहीं है, आप SO Q / A संरचना के बारे में अधिक पढ़ना चाहते हैं।
तेदोर संधू

2
@Mtz मेला काफी
रयान

1
यह वह नहीं है जो IMHO के लिए कहा गया था। दिखाए गए सरणी के लिए सही परिणाम होगा { "foo": {key: 'foo', val: 'bar'}, "hello": {key: 'hello', val: 'world'} }:। ध्यान दें कि प्रत्येक मूल तत्व को अपनी संपूर्णता में रखा जाना चाहिए । या क्यू के डेटा का उपयोग कर {"345": {id:345, name:"kumar"}, ...}:। FIX: कोड को बदल देंmap[obj.key] = obj;
टूलमेकरसेव

302

ES6 मैप का उपयोग करना ( बहुत अच्छी तरह से समर्थित ), आप यह कोशिश कर सकते हैं:

var arr = [
    { key: 'foo', val: 'bar' },
    { key: 'hello', val: 'world' }
];

var result = new Map(arr.map(i => [i.key, i.val]));

// When using TypeScript, need to specify type:
// var result = arr.map((i): [string, string] => [i.key, i.val])

// Unfortunately maps don't stringify well.  This is the contents in array form.
console.log("Result is: " + JSON.stringify([...result])); 
// Map {"foo" => "bar", "hello" => "world"}


4
यह भी नोट करना महत्वपूर्ण है कि किसी चीज को प्राप्त करने के लिए Mapआपको result.get(keyName)केवल विरोध के रूप में उपयोग करने की आवश्यकता है result[keyName]। यह भी ध्यान दें कि किसी भी वस्तु को कुंजी के रूप में इस्तेमाल किया जा सकता है, न कि केवल एक स्ट्रिंग के रूप में।
साइमन_वेअर

5
एक अन्य टाइपस्क्रिप्ट संस्करण इस तरह दिखेगा: var result = new Map(arr.map(i => [i.key, i.val] as [string, string]));जिसे समझना कुछ आसान हो सकता है। नोट as [string, string]प्रकार डाली गयी।
एलेक्सवी

जब मैं क्रोम v71 में इस कोड को चलाता हूं, तो मुझे अभी भी एक सरणी मिल रही है:Result is: [["foo","bar"],["hello","world"]]
जीन-फ्रांकोइस ब्यूचैम्प

पीएस resultओपी के अनुरोध के अनुसार एक हैश नहीं है।
जीन-फ्रांस्वा ब्यूचैम्प

1
एक अन्य प्रकार का संस्करण:var result = new Map<string, string>(arr.map(i => [i.key, i.val]));
अजीज जावेद


37

ES6 स्प्रेड + Object.assign का उपयोग करना:

array = [{key: 'a', value: 'b', redundant: 'aaa'}, {key: 'x', value: 'y', redundant: 'zzz'}]

const hash = Object.assign({}, ...array.map(s => ({[s.key]: s.value})));

console.log(hash) // {a: b, x: y}

2
बिल्कुल सही, बस मुझे जो चाहिए;)
पियरे

1
const hash = Object.assign({}, ...(<{}>array.map(s => ({[s.key]: s.value}))));टाइपस्क्रिप्ट के साथ काम करने के लिए यह परिवर्तन करना था।
रूबल .००

24

प्रसार ऑपरेटर का उपयोग करना:

const result = arr.reduce(
    (accumulator, target) => ({ ...accumulator, [target.key]: target.val }),
    {});

JsFiddle पर कोड स्निपेट का प्रदर्शन ।


7
मैं ठीक इसी वजह से यहाँ हूँ! कैसे फैलता है ऑपरेटर फिर से नियमित रूप से पुराने तरीके से प्रदर्शन करता है बस नई कुंजी असाइन करें और संचायक लौटाएं? जब से यह हर बार एक नई प्रतिलिपि बना रहा है, तब प्रसार खराब प्रदर्शन करेगा !
AMTourky

1
अब आप हर पुनरावृत्ति में फैल गए। यह reducer में उत्परिवर्तित करने के लिए सुरक्षित होना चाहिए। `` `कास्ट परिणाम = arr.reduce ((संचायक, लक्ष्य) => {संचायक [target.key] target.val; return संचायक}, {}); `` `
एमटीजे

17

आप Array.prototype.reduce () और वास्तविक जावास्क्रिप्ट मैप का उपयोग कर सकते हैं बजाय एक जावास्क्रिप्ट ऑब्जेक्ट के

let keyValueObjArray = [
  { key: 'key1', val: 'val1' },
  { key: 'key2', val: 'val2' },
  { key: 'key3', val: 'val3' }
];

let keyValueMap = keyValueObjArray.reduce((mapAccumulator, obj) => {
  // either one of the following syntax works
  // mapAccumulator[obj.key] = obj.val;
  mapAccumulator.set(obj.key, obj.val);

  return mapAccumulator;
}, new Map());

console.log(keyValueMap);
console.log(keyValueMap.size);

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

MDN दस्तावेज़ से उद्धरण :
ऑब्जेक्ट मैप्स के समान हैं, जिसमें दोनों आपको मानों की कुंजी सेट करने देते हैं, उन मानों को पुनः प्राप्त करते हैं, कुंजियों को हटाते हैं, और पता लगाते हैं कि क्या किसी कुंजी पर संग्रहीत है। इस वजह से (और क्योंकि कोई अंतर्निहित विकल्प नहीं था), वस्तुओं का उपयोग ऐतिहासिक रूप से मानचित्र के रूप में किया गया है; हालाँकि, ऐसे कुछ महत्वपूर्ण अंतर हैं जो कुछ मामलों में मानचित्र को बेहतर बनाने का उपयोग करते हैं:

  • किसी ऑब्जेक्ट की कुंजियाँ स्ट्रिंग्स और सिंबल हैं, जबकि वे फ़ंक्शंस, ऑब्जेक्ट्स और किसी भी आदिम सहित किसी मैप के लिए कोई भी मूल्य हो सकते हैं।
  • मानचित्र में कुंजियों का आदेश दिया जाता है, जबकि ऑब्जेक्ट में जोड़े गए कुंजी नहीं हैं। इस प्रकार, जब इस पर पुनरावृत्ति होती है, तो एक मैप ऑब्जेक्ट प्रविष्टि के क्रम में चाबियाँ देता है।
  • आप आकार की संपत्ति के साथ आसानी से मानचित्र का आकार प्राप्त कर सकते हैं, जबकि किसी ऑब्जेक्ट में गुणों की संख्या मैन्युअल रूप से निर्धारित की जानी चाहिए।
  • एक मानचित्र एक चलने योग्य है और इस प्रकार इसे सीधे पुनरावृत्त किया जा सकता है, जबकि किसी ऑब्जेक्ट पर पुनरावृत्ति करने के लिए कुछ फैशन में इसकी कुंजी प्राप्त करना और उन पर पुनरावृत्ति करना आवश्यक है।
  • ऑब्जेक्ट में एक प्रोटोटाइप होता है, इसलिए मानचित्र में डिफ़ॉल्ट कुंजियाँ होती हैं जो आपकी चाबियों से टकरा सकती हैं यदि आप सावधान नहीं हैं। ES5 के रूप में यह नक्शा = Object.create (नल) का उपयोग करके बाईपास किया जा सकता है, लेकिन यह शायद ही कभी किया जाता है।
  • एक नक्शा बार-बार जोड़े और प्रमुख जोड़े को हटाने वाले परिदृश्यों में बेहतर प्रदर्शन कर सकता है।

1
आपको एक तीर याद आ रहा है। बदलें (mapAccumulator, obj) {...}के लिए(mapAccumulator, obj) => {...}
mayid

15

आप नए का उपयोग कर सकते हैं Object.fromEntries() विधि का ।

उदाहरण:

const array = [
   {key: 'a', value: 'b', redundant: 'aaa'},
   {key: 'x', value: 'y', redundant: 'zzz'}
]

const hash = Object.fromEntries(
   array.map(e => [e.key, e.value])
)

console.log(hash) // {a: b, x: y}


12

es2015 संस्करण:

const myMap = new Map(objArray.map(obj => [ obj.key, obj.val ]));

4

यह वही है जो मैं टाइपस्क्रिप्ट में कर रहा हूं मेरे पास एक छोटा सा पुस्तकालय है जहां मैं इस तरह की चीजें डालता हूं

export const arrayToHash = (array: any[], id: string = 'id') => 
         array.reduce((obj, item) =>  (obj[item[id]] = item , obj), {})

उपयोग:

const hash = arrayToHash([{id:1,data:'data'},{id:2,data:'data'}])

या यदि आपके पास 'आईडी' के अलावा कोई पहचानकर्ता है

const hash = arrayToHash([{key:1,data:'data'},{key:2,data:'data'}], 'key')

यदि आप किसी ऑब्जेक्ट को कुंजी के रूप में उपयोग करना चाहते हैं, तो आपको ऑब्जेक्ट के बजाय मैप का उपयोग करना होगा क्योंकि टाइपस्क्रिप्ट आपको कुंजी के रूप में ऑब्जेक्ट का उपयोग नहीं करने देगा
Dany Dhondt

3

अन्य पोस्टरों द्वारा बताए गए तरीके से इसे करने के बेहतर तरीके हैं। लेकिन अगर मैं शुद्ध जेएस और राजभाषा तरीके से चिपकना चाहता हूं तो यह है:

var arr = [
    { key: 'foo', val: 'bar' },
    { key: 'hello', val: 'world' },
    { key: 'hello', val: 'universe' }
];

var map = {};
for (var i = 0; i < arr.length; i++) {
    var key = arr[i].key;
    var value = arr[i].val;

    if (key in map) {
        map[key].push(value);
    } else {
        map[key] = [value];
    }
}

console.log(map);

क्या इस विधि से कम विधि का उपयोग करने की सलाह दी जाती है। इस विधि का उपयोग करने का मन करता है। सब कुछ देखने के लिए सरल और आसान है।
संतोष योदिदी

मुझे इस दृष्टिकोण से प्यार है। मुझे लगता है कि कभी-कभी सबसे सरल कोड सबसे अच्छा होता है। लोगों को आजकल उत्परिवर्तन द्वारा बंद कर दिया जाता है, लेकिन जब तक यह निहित है, तब तक उत्परिवर्तन वास्तव में बहुत बढ़िया और प्रदर्शनकारी है।
लुइस ऐसिटूनो

3

यदि आप नए ES6 मैप में कनवर्ट करना चाहते हैं तो ऐसा करें:

var kvArray = [['key1', 'value1'], ['key2', 'value2']];
var myMap = new Map(kvArray);

आपको इस प्रकार के मानचित्र का उपयोग क्यों करना चाहिए? अच्छा है कि आप पर निर्भर है। इस पर एक नजर ।


2

सरल जावास्क्रिप्ट का उपयोग करना

var createMapFromList = function(objectList, property) {
    var objMap = {};
    objectList.forEach(function(obj) {
      objMap[obj[property]] = obj;
    });
    return objMap;
  };
// objectList - the array  ;  property - property as the key

3
इस उदाहरण में .map (...) का उपयोग नहीं किया जाता है क्योंकि आप इसमें कुछ भी नहीं लौटाते हैं? मैं इस मामले में सुझाव देना चाहूंगा।
cuddlecheek

2

के साथ lodash:

const items = [
    { key: 'foo', value: 'bar' },
    { key: 'hello', value: 'world' }
];

const map = _.fromPairs(items.map(item => [item.key, item.value]));

console.log(map); // { foo: 'bar', hello: 'world' }

1

reduceउपयोग पर एक छोटा सा सुधार :

var arr = [
    { key: 'foo', val: 'bar' },
    { key: 'hello', val: 'world' }
];

var result = arr.reduce((map, obj) => ({
    ...map,
    [obj.key] = obj.val
}), {});

console.log(result);
// { foo: 'bar', hello: 'world' }

क्या यह अन्य उत्तर की तुलना में तेज है ?
orad

@ याड शायद नहीं, क्योंकि यह संचायक को फैलाता है और प्रत्येक पुनरावृत्ति को नई वस्तु बनाता है।
लकीलोके

1

प्रयत्न

let toHashMap = (a,f) => a.reduce((a,c)=> (a[f(c)]=c,a),{});


0

वस्तु की विशेषता मान द्वारा अनुक्रमित हैश मैप में वस्तुओं के सरणी में परिवर्तित करने के लिए जावास्क्रिप्ट में बनाई गई छोटी स्निपेट निम्नलिखित है। आप गतिशील रूप से (रन समय) हैश मानचित्र की कुंजी का मूल्यांकन करने के लिए एक फ़ंक्शन प्रदान कर सकते हैं।

function isFunction(func){
    return Object.prototype.toString.call(func) === '[object Function]';
}

/**
 * This function converts an array to hash map
 * @param {String | function} key describes the key to be evaluated in each object to use as key for hasmap
 * @returns Object
 * @Example 
 *      [{id:123, name:'naveen'}, {id:345, name:"kumar"}].toHashMap("id")
        Returns :- Object {123: Object, 345: Object}

        [{id:123, name:'naveen'}, {id:345, name:"kumar"}].toHashMap(function(obj){return obj.id+1})
        Returns :- Object {124: Object, 346: Object}
 */
Array.prototype.toHashMap = function(key){
    var _hashMap = {}, getKey = isFunction(key)?key: function(_obj){return _obj[key];};
    this.forEach(function (obj){
        _hashMap[getKey(obj)] = obj;
    });
    return _hashMap;
};

आप यहाँ gist पा सकते हैं: https://gist.github.com/naveen-ithappu/c7cd5026f6002131c1fa


11
कृपया, कृपया, कृपया विस्तार करने की अनुशंसा न करें Array.prototype!
jmar777

हाँ! मैंने देखा। मैंने शुरू में सोचा था कि यह एक प्रस्तावित उत्तर था :)
jmar777
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.