ऑब्जेक्ट के लिए मानचित्र फ़ंक्शन (सरणियों के बजाय)


1063

मेरे पास एक वस्तु है:

myObject = { 'a': 1, 'b': 2, 'c': 3 }

मैं एक देशी विधि की तलाश में हूं, Array.prototype.mapजिसका उपयोग इस प्रकार किया जाएगा:

newObject = myObject.map(function (value, label) {
    return value * value;
});

// newObject is now { 'a': 1, 'b': 4, 'c': 9 }

क्या जावास्क्रिप्ट mapवस्तुओं के लिए इस तरह के एक समारोह है? (मैं Node.JS के लिए यह चाहता हूं, इसलिए मुझे क्रॉस-ब्राउज़र मुद्दों की परवाह नहीं है।)


1
अधिकांश उत्तर उपयोग करते हैं Object.keys, जिसमें कोई अच्छी तरह से परिभाषित आदेश नहीं है। यह समस्याग्रस्त हो सकता है, मैं Object.getOwnPropertyNamesइसके बजाय उपयोग करने का सुझाव देता हूं ।
ओरिऑल

14
मेरे लिए आश्चर्यजनक है कि जेएस ने अविश्वसनीय रूप से अल्पविकसित कार्य के लिए प्रदान नहीं किया।
jchook

3
@ ऑरोल क्या आप इसके बारे में निश्चित हैं? MDN वेब डॉक्स के अनुसार, सरणी तत्वों का क्रम Object.keysऔर के बीच संगत है Object.getOwnPropertyNames। देखें डेवलपर.
बार्ट

@Bart Object.keysकार्यान्वयन-निर्भर का आदेश है। देखें stackoverflow.com/a/30919039/1529630
ओरिएल

4
@ ऑरिऑल आप वैसे भी वस्तुओं में कुंजियों के क्रम पर भरोसा करने के लिए नहीं हैं, इसलिए इस सवाल के लिए यह अप्रासंगिक है - क्योंकि उन्होंने कभी यह निर्दिष्ट नहीं किया कि उनके लिए यह आदेश मायने रखता है। और अगर उसे आदेश दिया जाता है, तो उसे किसी भी तरह से किसी वस्तु का उपयोग नहीं करना चाहिए।
बीटी

जवाबों:


1540

ऑब्जेक्ट के mapलिए कोई मूल नहीं है Object, लेकिन इस बारे में कैसे:

var myObject = { 'a': 1, 'b': 2, 'c': 3 };

Object.keys(myObject).map(function(key, index) {
  myObject[key] *= 2;
});

console.log(myObject);
// => { 'a': 2, 'b': 4, 'c': 6 }

लेकिन आप आसानी से किसी वस्तु का उपयोग कर सकते हैं for ... in:

var myObject = { 'a': 1, 'b': 2, 'c': 3 };

for (var key in myObject) {
  if (myObject.hasOwnProperty(key)) {
    myObject[key] *= 2;
  }
}

console.log(myObject);
// { 'a': 2, 'b': 4, 'c': 6 }

अपडेट करें

बहुत से लोग इस बात का उल्लेख कर रहे हैं कि पिछले तरीके नई वस्तु नहीं लौटाते हैं, बल्कि वस्तु पर ही काम करते हैं। उस मामले के लिए मैं एक और समाधान जोड़ना चाहता था जो एक नई वस्तु लौटाता है और मूल वस्तु को छोड़ देता है:

var myObject = { 'a': 1, 'b': 2, 'c': 3 };

// returns a new object with the values at each key mapped using mapFn(value)
function objectMap(object, mapFn) {
  return Object.keys(object).reduce(function(result, key) {
    result[key] = mapFn(object[key])
    return result
  }, {})
}

var newObject = objectMap(myObject, function(value) {
  return value * 2
})

console.log(newObject);
// => { 'a': 2, 'b': 4, 'c': 6 }

console.log(myObject);
// => { 'a': 1, 'b': 2, 'c': 3 }

Array.prototype.reduceवर्तमान के साथ पिछले मान को विलय करके एकल मान के लिए एक सरणी को कम कर देता है। श्रृंखला एक खाली वस्तु द्वारा आरंभ की जाती है {}। प्रत्येक पुनरावृत्ति पर myObjectमूल्य के रूप में दो बार कुंजी के साथ एक नई कुंजी जोड़ी जाती है।

अपडेट करें

नई ईएस 6 विशेषताओं के साथ, व्यक्त करने का एक और अधिक सुंदर तरीका है objectMap

const objectMap = (obj, fn) =>
  Object.fromEntries(
    Object.entries(obj).map(
      ([k, v], i) => [k, fn(v, k, i)]
    )
  )
  
const myObject = { a: 1, b: 2, c: 3 }

console.log(objectMap(myObject, v => 2 * v)) 


3
हां, मैं उस तरह की समस्या के लिए अपने समाधान की सिफारिश नहीं करूंगा। यही कारण है कि मैंने एक वैकल्पिक, बेहतर समाधान के साथ अपना जवाब अपडेट किया।
अंबरलाम्प्स

1
मैंने अपना उत्तर अपडेट कर दिया है - ऐसा लगता है (प्रश्न को फिर से पढ़ने पर) कि ओपी उसी कुंजी के साथ एक नई वस्तु चाहता है , जहां मान आपूर्ति किए गए फ़ंक्शन के साथ उत्परिवर्तित थे, और मूल वस्तु को संशोधित करने के लिए नहीं।
अलनीतक

13
@KhalilRavanna मुझे लगता है कि आपने यहाँ कोड को गलत बताया है - यह उत्तर mapसही ढंग से उपयोग नहीं कर रहा है क्योंकि यह ऐसा नहीं कर रहा है return- यह एक ऐसा अपमानजनक है mapजैसे कि यह एक forEachकॉल हो। यदि वह वास्तव में करता है, return myObject[value] * 2 तो परिणाम एक सरणी होगा जिसमें मूल मूल्यों को दोगुना किया जाएगा, एक वस्तु के बजाय मूल कुंजी जिसमें दोगुने मान होंगे, बाद में स्पष्ट रूप से ओपी के लिए पूछा जाएगा।
अलनीतक

3
@Amberlamps आपका .reduceउदाहरण ठीक है, लेकिन IMHO यह अभी भी .mapऑब्जेक्ट्स की सुविधा के लिए एक लंबा रास्ता तय करता है , क्योंकि आपके .reduceकॉलबैक में न केवल उस तरीके से मेल खाना है जो .reduceकाम करता है, बल्कि यह भी आवश्यक है कि myObjectलेक्सिकल स्कोप में उपलब्ध हो। विशेष रूप से उत्तरार्द्ध कॉलबैक में केवल एक फ़ंक्शन संदर्भ पास करना असंभव बनाता है, इसके बजाय इन-प्लेस अनाम फ़ंक्शन की आवश्यकता होती है।
अलनीतक

8
टीबीएच मैंने एक उत्तर दिया है जो केवल (या मूल रूप से) इस उत्तर में प्रस्तुत दूसरा समाधान प्रदान करता है। पहला काम करता है और जरूरी नहीं कि गलत हो, लेकिन जैसा कि दूसरों ने कहा है, मैं उस तरह से इस्तेमाल किए जा रहे नक्शे को देखना पसंद नहीं करता। जब मैं नक्शा देखता हूं, तो मेरा दिमाग स्वचालित रूप से "अपरिवर्तनीय डेटा संरचना" सोच रहा है
mjohnsonengr

307

प्लेन JS ( ES6 / ES2015 ) में तत्काल चर असाइनमेंट के साथ एक लाइनर के बारे में कैसे ?

का इस्तेमाल कर रही प्रसार ऑपरेटर और गणना कुंजी नाम वाक्य रचना:

let newObj = Object.assign({}, ...Object.keys(obj).map(k => ({[k]: obj[k] * obj[k]})));

jsbin

एक और संस्करण का उपयोग कम करें:

let newObj = Object.keys(obj).reduce((p, c) => ({...p, [c]: obj[c] * obj[c]}), {});

jsbin

एक समारोह के रूप में पहला उदाहरण:

const oMap = (o, f) => Object.assign({}, ...Object.keys(o).map(k => ({ [k]: f(o[k]) })));

// To square each value you can call it like this:
let mappedObj = oMap(myObj, (x) => x * x);

jsbin

आप एक नेस्टेड वस्तु मैप करने के लिए चाहते हैं रिकर्सिवली एक में कार्यात्मक शैली, तो वह ऐसा किया जा सकता है:

const sqrObjRecursive = obj =>
  Object.keys(obj).reduce(
    (newObj, key) =>
      obj[key] && typeof obj[key] === "object"
        ? { ...newObj, [key]: sqrObjRecursive(obj[key]) } // recurse.
        : { ...newObj, [key]: obj[key] * obj[key] }, // square val.
    {}
  );       

jsbin

या अधिक अनिवार्य रूप से, इस तरह:

const sqrObjRecursive = obj => {
  Object.keys(obj).forEach(key => {
    if (typeof obj[key] === "object") obj[key] = sqrObjRecursive(obj[key]);
    else obj[key] = obj[key] * obj[key];
  });
  return obj;
};

jsbin

ES7 / ES2016 के बाद से आप इस तरह के Object.entries()बजाय उपयोग कर सकते हैं Object.keys():

let newObj = Object.assign({}, ...Object.entries(obj).map(([k, v]) => ({[k]: v * v})));

ES2019 पेश किया Object.fromEntries(), जो इसे और भी सरल बनाता है :

let newObj = Object.fromEntries(Object.entries(obj).map(([k, v]) => [k, v * v]));


निहित गुण और प्रोटोटाइप श्रृंखला:

कुछ दुर्लभ स्थिति में आपको एक क्लास जैसी ऑब्जेक्ट को मैप करने की आवश्यकता हो सकती है , जो इसके प्रोटोटाइप-चेन पर एक विरासत में मिली वस्तु के गुण रखती है । ऐसे मामलों में Object.keys()काम नहीं करेगा, क्योंकि विरासत में मिली संपत्तियों की Object.keys()गणना नहीं होती है । यदि आपको विरासत में मिली संपत्ति को मैप करने की आवश्यकता है , तो आपको उपयोग करना चाहिए ।for (key in myObj) {...}

यहां एक ऑब्जेक्ट का एक उदाहरण है जो किसी अन्य ऑब्जेक्ट के गुणों को विरासत में मिला है और Object.keys()ऐसे परिदृश्य में कैसे काम नहीं करता है।

const obj1 = { 'a': 1, 'b': 2, 'c': 3}
const obj2 = Object.create(obj1);  // One of multiple ways to inherit an object in JS.

// Here you see how the properties of obj1 sit on the 'prototype' of obj2
console.log(obj2)  // Prints: obj2.__proto__ = { 'a': 1, 'b': 2, 'c': 3}

console.log(Object.keys(obj2));  // Prints: an empty Array.

for (key in obj2) {
  console.log(key);              // Prints: 'a', 'b', 'c'
}

jsbin

हालांकि, कृपया मुझे एक एहसान करो और विरासत से बचें । :-)


1
सुंदर, लेकिन मुझे इस तथ्य से पकड़ लिया गया कि Object.keysविरासत में मिली संपत्तियों की गणना नहीं है। मेरा सुझाव है कि आप एक चेतावनी जोड़ें।
डेविड ब्रौन

अपने उत्तर को छोटा करने के लिए, बस उपयोग करें Object.entries({a: 1, b: 2, c: 3})

1
आपके पास कुछ टाइपोस हैं (आप (o, f)तर्क के रूप में संदर्भित करते हैं लेकिन objशरीर में उपयोग करते हैं।
kazhel

4
हाँ और फिर अगले व्यक्ति को कुछ मिनट खर्च करने दें ताकि पता चल सके कि यह कार्य क्या है? :)
एंड्री पोपोव

1
खाली वस्तु होने पर समाधान Object.assign(...Object.entries(obj).map(([k, v]) => ({[k]: v * v})))काम नहीं करता objहै। में बदलें: Object.assign({}, ...Object.entries(obj).map(([k, v]) => ({[k]: v * v})))
ब्लैककटवेब

115

कोई देशी तरीका नहीं है, लेकिन लॉश # mapValues शानदार ढंग से काम करेंगे

_.mapValues({ 'a': 1, 'b': 2, 'c': 3} , function(num) { return num * 3; });
// → { 'a': 3, 'b': 6, 'c': 9 }

6
केवल एक फ़ंक्शन के लिए अतिरिक्त HTTP कॉल और अतिरिक्त लाइब्रेरी जोड़ने की आवश्यकता नहीं है। किसी भी स्थिति में, यह उत्तर अब पुराना हो गया है और आप केवल Object.entries({a: 1, b: 2, c: 3})एक सरणी प्राप्त करने के लिए कॉल कर सकते हैं ।

10
एक सरणी उपयोगी क्यों हो रही है? आवश्यकता एक मैप की गई वस्तु के लिए थी। इसके अलावा, इस प्रकार की चीज़ों के लिए अनिवार्य रूप से निर्मित एक लोकप्रिय पुस्तकालय, लोडश का उपयोग करने में कोई निहित HTTP कॉल नहीं है, हालांकि ईएस 6 ने कुछ हद तक उपयोगिता फ़ंक्शन पुस्तकालयों का उपयोग करने की आवश्यकता को समाप्त कर दिया है।
corse32 13

2
लोदाश को खींचने के लिए अतिरिक्त HTTP कॉल, मुझे लगता है। यदि यह आपका एकमात्र उपयोग मामला है, तो वास्तव में यह एक ओवरकिल है। बहरहाल, यह समझ में आता है कि लोदश के लिए यह उत्तर चारों ओर एक व्यापक पुस्तकालय है।
igorsantos07

2
उल्लेख नहीं करने के लिए आपको वास्तव में उपयोग करना चाहिए _.map()ताकि आपको ओपी द्वारा आवश्यक - दूसरे तर्क के रूप में कुंजी मिल जाए।
igorsantos07

57

एक लिखना बहुत आसान है:

Object.map = function(o, f, ctx) {
    ctx = ctx || this;
    var result = {};
    Object.keys(o).forEach(function(k) {
        result[k] = f.call(ctx, o[k], k, o); 
    });
    return result;
}

उदाहरण कोड के साथ:

> o = { a: 1, b: 2, c: 3 };
> r = Object.map(o, function(v, k, o) {
     return v * v;
  });
> r
{ a : 1, b: 4, c: 9 }

एनबी: यह संस्करण भी आपको विधि की thisतरह कॉलबैक के लिए संदर्भ सेट करने की अनुमति देता है (वैकल्पिक रूप से) Array

EDIT - का उपयोग हटाने के लिए बदल दिया गया है Object.prototype, यह सुनिश्चित करने के लिए कि यह mapऑब्जेक्ट पर किसी भी मौजूदा संपत्ति के साथ टकराव नहीं करता है ।


3
ठीक है। :) इस सवाल पर एक टिप्पणी ने मुझे यहाँ लाया। मैं इसे +1 करूँगा क्योंकि स्वीकृत उत्तर स्पष्ट रूप से गलत उपयोग mapकर रहा है, लेकिन मुझे यह कहना होगा कि संशोधन Object.prototypeमेरे साथ अच्छी तरह से नहीं बैठता है, भले ही यह बहुत अच्छा न हो।
JLRishe

2
@JLRishe धन्यवाद ईएस 5 में आईएमएचओ वास्तव में अन्य तरीकों के साथ टकराव के (सैद्धांतिक) जोखिम के अलावा अन्य को संशोधित करने का कोई कारण नहीं है Object.prototype। FWIW, मैं समझ नहीं पा रहा हूं कि दूसरे उत्तर को जितने वोट मिले, यह पूरी तरह से गलत है।
अलनीतक

7
@JLRishe तुम एक पुराने गीजर हो ... समय के साथ जाओ और उस प्रोटोटाइप को संशोधित करो!
निक मैनिंग

12
@NickManning आप युवा व्हाट्सएप और अपने गैरजिम्मेदार व्यवहार के लिए। मेरे आँगन से उतरो!
JLRishe

3
यह पहले से ही काम नहीं करता है o = {map: true, image: false}:। आप कर रहे हैं यह खतरे में डालकर सिर्फ लिखने के o.map(fn)बजायmap(o,fn)
fregante

25

आप उपयोग कर सकते हैं Object.keysऔर फिर forEachकुंजियों के दिए गए सरणी पर:

var myObject = { 'a': 1, 'b': 2, 'c': 3 },
    newObject = {};
Object.keys(myObject).forEach(function (key) {
    var value = myObject[key];
    newObject[key] = value * value;
});

या अधिक मॉड्यूलर फैशन में:

function map(obj, callback) {
    var result = {};
    Object.keys(obj).forEach(function (key) {
        result[key] = callback.call(obj, obj[key], key, obj);
    });
    return result;
}

newObject = map(myObject, function(x) { return x * x; });

ध्यान दें कि Object.keysएक सरणी देता है जिसमें केवल ऑब्जेक्ट के स्वयं के असंख्य गुण होते हैं, इस प्रकार यह for..inएक hasOwnPropertyचेक के साथ लूप की तरह व्यवहार करता है ।


20

यह सीधे bs है, और JS समुदाय में हर कोई इसे जानता है। वहाँ चाहिए इस कार्यक्षमता हो:

const obj1 = {a:4, b:7};
const obj2 = Object.map(obj1, (k,v) => v + 5);

console.log(obj1); // {a:4, b:7}
console.log(obj2); // {a:9, b:12}

यहाँ भोले का कार्यान्वयन है:

Object.map = function(obj, fn, ctx){

    const ret = {};

    for(let k of Object.keys(obj)){
        ret[k] = fn.call(ctx || null, k, obj[k]);
    });

    return ret;
};

यह अपने आप को हर समय लागू करने के लिए सुपर कष्टप्रद है;)

यदि आप कुछ अधिक परिष्कृत चाहते हैं, तो यह ऑब्जेक्ट क्लास के साथ हस्तक्षेप नहीं करता है, यह कोशिश करें:

let map = function (obj, fn, ctx) {
  return Object.keys(obj).reduce((a, b) => {
    a[b] = fn.call(ctx || null, b, obj[b]);
    return a;
  }, {});
};


const x = map({a: 2, b: 4}, (k,v) => {
    return v*2;
});

लेकिन इस मानचित्र फ़ंक्शन को ऑब्जेक्ट में जोड़ना सुरक्षित है, बस Object.prototyp में नहीं जोड़ें।

Object.map = ... // fairly safe
Object.prototype.map ... // not ok

आप इस फ़ंक्शन को वैश्विक Objectऑब्जेक्ट में क्यों जोड़ते हैं ? बस है const mapObject = (obj, fn) => { [...]; return ret; }
अंबरलैम्प्स

7
क्योंकि यह ऑब्जेक्ट पर एक विधि होना चाहिए :)
अलेक्जेंडर मिल्स

1
जब तक हम Object.prototype के साथ गड़बड़ नहीं करते हैं तब तक हम ठीक होना चाहिए
अलेक्जेंडर मिल्स

1
अगर नक्शा सिर्फ एक यादृच्छिक अस्पष्ट बात थी, तो निश्चित रूप से। लेकिन .mapआम तौर पर एक फ़नकार इंटरफ़ेस के रूप में समझा जाता है, और "ऑब्जेक्ट" के लिए फ़ंक्टर की कोई एक परिभाषा नहीं है क्योंकि वस्तुतः जावास्क्रिप्ट में कुछ भी एक वस्तु हो सकती है, जिसमें अपने स्वयं के बहुत विशिष्ट और परिभाषित .map इंटरफेस / तर्क सहित चीजें शामिल हैं।
Dtipson

1
मेरी राय में, कॉलबैक का पहला तर्क स्वयं को पुनरावृत्त तत्व होना चाहिए, कुंजी नहीं। उदाहरण के लिए, मुझे लगता है कि मुझे वही वस्तु देनी चाहिए, क्योंकि यह सामान्य रूप से सामान्य मानचित्र के साथ होता है: Object.map ({Prop: 1}, el => el) लेकिन यह एक ही कुंजी नाम के मान के साथ कुंजियाँ देता है ...
Gleb Dolzikov

17

मैं एक सरणी के लिए किसी ऑब्जेक्ट को मैप करने के लिए खोजने और उत्तर देने के लिए यहां आया था और परिणामस्वरूप यह पृष्ठ मिला। यदि आप यहां आए थे तो मैं उसी उत्तर की तलाश में था, यहां बताया गया है कि आप किसी सरणी में कैसे मैप और ऑब्जेक्ट कर सकते हैं।

आप इस तरह से ऑब्जेक्ट से एक नया सरणी वापस करने के लिए मानचित्र का उपयोग कर सकते हैं:

var newObject = Object.keys(myObject).map(function(key) {
   return myObject[key];
});

6
यह दूरस्थ रूप से काम नहीं करता है - यह सिर्फ ऑब्जेक्ट के मूल्यों की एक सरणी देता है, एक नई वस्तु नहीं। मुझे विश्वास नहीं हो रहा है कि इसमें कई अप-वोट हैं।
अलनीतक

1
आप सही हैं, यह प्रश्न का सही उत्तर नहीं देता है क्योंकि वे किसी वस्तु और वस्तु को मैप करने के लिए उत्तर की तलाश में थे। मैं एक सरणी के लिए किसी ऑब्जेक्ट को मैप करने के लिए एक उत्तर की तलाश में यहां आया था और इस पृष्ठ को एक परिणाम के रूप में मिला, इसलिए मैं अपना उत्तर छोड़ दूंगा और इसे प्रतिबिंबित करने के लिए संपादित करूंगा कि यह उन लोगों के लिए एक वैकल्पिक उत्तर है, जो यहां परिणाम के रूप में प्राप्त कर सकते हैं। arrays के लिए एक वस्तु मानचित्रण के लिए देख रहे हैं।
जोट्रॉन

5
ES7 में, जो तुच्छ रूप से होगाObject.values(myObject)
Alnitak

1
यह जानना अच्छा है, लेकिन कुछ लोगों को अभी भी विरासत कोड का उपयोग करना है।
जोट्रॉन

const obj = {foo: 'bar', baz: 42}; console.log (Object.entries (obj)); // [['फू', 'बार'], ['
बाज

12

स्वीकृत उत्तर में दो कमियां हैं:

  • यह दुरुपयोग करता है Array.prototype.reduce, क्योंकि कम करने का मतलब है कि एक समग्र प्रकार की संरचना को बदलना, जो इस मामले में नहीं होता है।
  • यह विशेष रूप से पुन: प्रयोज्य नहीं है

एक ES6 / ES2015 कार्यात्मक दृष्टिकोण

कृपया ध्यान दें कि सभी फ़ंक्शंस को कर्फ़ेड रूप में परिभाषित किया गया है।

// small, reusable auxiliary functions

const keys = o => Object.keys(o);

const assign = (...o) => Object.assign({}, ...o);

const map = f => xs => xs.map(x => f(x));

const mul = y => x => x * y;

const sqr = x => mul(x) (x);


// the actual map function

const omap = f => o => {
  o = assign(o); // A
  map(x => o[x] = f(o[x])) (keys(o)); // B
  return o;
};


// mock data

const o = {"a":1, "b":2, "c":3};


// and run

console.log(omap(sqr) (o));
console.log(omap(mul(10)) (o));

  • लाइन ए oमें पुन: असाइन किया गया है। चूंकि जावास्क्रिप्ट साझा करने से संदर्भ मान गुजरता है , इसलिए उथली प्रति oउत्पन्न होती है। अब हम माता-पिता के दायरे में उत्परिवर्तन oके omapबिना भीतर परिवर्तन करने oमें सक्षम हैं ।
  • लाइन बी mapके रिटर्न वैल्यू को नजरअंदाज कर दिया जाता है, क्योंकि mapएक उत्परिवर्तन करता है o। चूंकि यह साइड इफेक्ट भीतर रहता है omapऔर मूल दायरे में दिखाई नहीं देता है, इसलिए यह पूरी तरह स्वीकार्य है।

यह सबसे तेज़ समाधान नहीं है, लेकिन एक घोषणात्मक और पुन: प्रयोज्य है। यहाँ एक-पंक्ति के रूप में एक ही कार्यान्वयन है, रसीला लेकिन कम पठनीय:

const omap = f => o => (o = assign(o), map(x => o[x] = f(o[x])) (keys(o)), o);

परिशिष्ट - वस्तुएं डिफ़ॉल्ट रूप से चलने योग्य क्यों नहीं हैं?

ES2015 ने पुनरावृत्त और पुनरावृत्त प्रोटोकॉल निर्दिष्ट किए। लेकिन वस्तुएं अभी भी चलने योग्य नहीं हैं और इस प्रकार अनुपयोगी नहीं हैं। इसका कारण डेटा और प्रोग्राम स्तर का मिश्रण है


1
कुछ हद तक इंजीनियर जैसा दिखता है; मैं अनिवार्य रूप से एक लूप के लिए 6 कार्यों को गिनता हूं। अन्य समाधान कहीं अधिक सरल हैं और स्वीकृत उत्तर 5 गुना तेज है।
11

4
@ bfred.it आपकी टिप्पणी का उद्देश्य क्या है? यदि आपको माइक्रो-ऑप्टिमाइज़ेशन पसंद है तो आपको इसका उपयोग नहीं करना चाहिए Array.prototype.reduce। मैं यहाँ स्पष्ट करना चाहता हूँ कि स्वीकृत उत्तर किसी भी तरह "गाली" है Array.prototype.reduceऔर एक विशुद्ध रूप से कार्यात्मक मानचित्रण कैसे लागू किया जा सकता है। यदि आप कार्यात्मक प्रोग्रामिंग में रुचि नहीं रखते हैं, तो बस मेरे उत्तर को अनदेखा करें।

2
"कम करने का मतलब है कि एक समग्र प्रकार की संरचना को बदलना" मुझे नहीं लगता कि यह सच है। एक Array.reduce जो सटीक समान लंबाई का एक नया सरणी पैदा करता है या यहां तक ​​कि सटीक समान मान पूरी तरह से वैध है। कम करने के लिए नक्शा और / या फिल्टर (या दोनों, एक जटिल ट्रांसड्यूसर के रूप में, जिसके लिए कम करने का आधार है) की कार्यक्षमता को फिर से बनाने के लिए उपयोग किया जा सकता है। एफपी में, यह एक प्रकार का गुना है, और एक ही प्रकार के साथ समाप्त होने वाला एक गुना अभी भी एक गुना है।
डीवीप्सन

2
@Dtipson तुम बिल्कुल सही हो। A (फ़नकार) की foldतुलना में अधिक सामान्य है map। हालांकि, 2016 के मध्य से यह मेरा ज्ञान था। यह आधा अनंत काल है: D

1
हा, हाँ। यह महसूस करने में मुझे कई साल लग गए कि यह सारा सामान कैसा है, और शर्तों और इंटरफेस का व्यापक पारिस्थितिकी तंत्र। चीजें हैं जो ऐसा लगता है कि वे इतना आसान हो जाएगा असंभव हो जटिल है, और कुछ सामान है कि असंभव काफी सार दूर लगता है। :)
Dtipson

10

जावास्क्रिप्ट को सिर्फ नई Object.fromEntriesविधि मिली ।

उदाहरण

function mapObject (obj, fn) {
  return Object.fromEntries(
    Object
      .entries(obj)
      .map(fn)
  )
}

const myObject = { a: 1, b: 2, c: 3 }
const myNewObject = mapObject(myObject, ([key, value]) => ([key, value * value]))
console.log(myNewObject)

व्याख्या

ऊपर दिया गया कोड ऑब्जेक्ट को नेस्टेड ऐरे ( [[<key>,<value>], ...]) में परिवर्तित करता है, जिसे आप मैप कर सकते हैं। Object.fromEntriesArray को वापस किसी ऑब्जेक्ट में कनवर्ट करता है।

इस पैटर्न के बारे में अच्छी बात यह है कि आप मैपिंग करते समय आसानी से ऑब्जेक्ट कुंजियों को ध्यान में रख सकते हैं।

प्रलेखन

ब्राउज़र का समर्थन

Object.fromEntriesवर्तमान में केवल इन ब्राउज़रों / इंजनों द्वारा समर्थित है , फिर भी वहाँ पॉलीफ़िल उपलब्ध हैं (जैसे @ बैबल / पॉलीफ़िल )।


2
असल में, Object.fromEntriesइसके विपरीत है Object.entriesObject.entriesऑब्जेक्ट को कुंजी-मूल्य जोड़े की सूची में कनवर्ट करता है। Object.fromEntriesकुंजी-मूल्य जोड़े की एक सूची को एक वस्तु में परिवर्तित करता है।
orad

8

न्यूनतम संस्करण (es6):

Object.entries(obj).reduce((a, [k, v]) => (a[k] = v * v, a), {})

मुझे लगता है कि यह एक टाइपो के कारण गलत है, मुझे लगता है कि आप मतलब => Object.entries(obj).reduce((a, [k, v]) => [a[k] = v * v, a], {}), कोष्ठक के बजाय कोन-कोष्ठक।
सिकंदर मिल्स

@AlexanderMills, मेरा कोड सही है। कोष्ठक के अंदर अल्पविराम ऑपरेटर के बारे में अधिक पढ़ें: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
युकुलिये

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

1
मूल रूप से, मेरा कोड इसके बराबर है:Object.entries(obj).reduce((a, [k, v]) => {a[k] = v * v; return a}, {})
युकुएल

1
बहुत बढ़िया जवाब। Object.entries().reduceईएस 6 + के साथ मुझे लगता है कि सबसे अच्छा समाधान है। यदि अधिक रेडिएटर में एक returnबयान का उपयोग किया जाता है, तो इसके बजाय implicit returnऔर अधिक उठाव मिलता है comma- जो कि साफ-सुथरा है लेकिन
आईएमएचओ

7

अधिकतम प्रदर्शन के लिए।

यदि आपकी वस्तु अक्सर नहीं बदलती है, लेकिन मुझे अक्सर देशी मैप का उपयोग करके कैश के रूप में उपयोग करने की आवश्यकता होती है।

// example object
var obj = {a: 1, b: 2, c: 'something'};

// caching map
var objMap = new Map(Object.entries(obj));

// fast iteration on Map object
objMap.forEach((item, key) => {
  // do something with an item
  console.log(key, item);
});

Object.entries पहले से ही क्रोम, एज, फ़ायरफ़ॉक्स और बीटा ओपेरा में काम करता है इसलिए यह भविष्य में प्रूफ सुविधा है। यह ES7 से है इसलिए इसे पॉलीफ़िल करें https://github.com/es-shims/Object.entries IE के लिए जहां यह काम नहीं करता है।


विनाशकारी का उपयोग करने के बारे में कैसे ?
Константин Ван

1
@ K._ यह बहुत धीमा हुआ करता था, लेकिन मुझे अब प्रदर्शन के बारे में पता नहीं है। ऐसा लगता है कि V8 v 5.6 विनाशकारी के लिए कुछ अनुकूलन प्रस्तुत करता है लेकिन इसे v8project.blogspot.co.uk
पावेल

या, कम प्रदर्शन करने वाले es7 लेकिन अपरिवर्तनीय:const fn = v => v * 2; const newObj = Object.entries(myObject).reduce((acc, [k,v]) => Object.assign({}, acc, {[k]: fn(v)}), {});
mikebridge

मैं सोच रहा हूँ क्यों अन्य जवाब में से कोई भी Object.entries का उपयोग करें। यह कुंजियों पर चलने और obj [कुंजी] का उपयोग करने से बहुत साफ है।
corwin.amber

6

आप mapविधि और forEachसरणियों पर उपयोग कर सकते हैं, लेकिन यदि आप इसका उपयोग करना चाहते हैं Objectतो आप नीचे दिए गए मोड़ के साथ इसका उपयोग कर सकते हैं:

जावास्क्रिप्ट (ES6) का उपयोग करना

var obj = { 'a': 2, 'b': 4, 'c': 6 };   
Object.entries(obj).map( v => obj[v[0]] *= v[1] );
console.log(obj); //it will log as {a: 4, b: 16, c: 36}

var obj2 = { 'a': 4, 'b': 8, 'c': 10 };
Object.entries(obj2).forEach( v => obj2[v[0]] *= v[1] );
console.log(obj2); //it will log as {a: 16, b: 64, c: 100}

JQuery का उपयोग करना

var ob = { 'a': 2, 'b': 4, 'c': 6 };
$.map(ob, function (val, key) {
   ob[key] *= val;
});
console.log(ob) //it will log as {a: 4, b: 16, c: 36}

या आप अन्य छोरों का उपयोग भी कर सकते हैं जैसे $.eachकि उदाहरण के लिए नीचे दी गई विधि:

$.each(ob,function (key, value) {
  ob[key] *= value;
});
console.log(ob) //it will also log as {a: 4, b: 16, c: 36}

कहाँ $है jquery?
मास्टरएक्सिलो

हां आप $ 12 और jQuery का उपयोग कर सकते हैं
हरितसिंह गोहिल

1
@ रोनाल्ड ने मुझे गलत समझा है, मेरे अपडेट किए गए उत्तर को देखें, डाउनवॉटिंग के लिए धन्यवाद लेकिन वास्तव में मेरी गलती से अवगत कराने के लिए, समुदाय में सुधार के लिए धन्यवाद।
हरितसिंह गोहिल

@bcoughlan हाँ यह बिल्कुल वही है जो मैंने टिप्पणी में लिखा है, यह संख्याओं को बढ़ा रहा है, फिर आप क्या चाहते हैं?
हरितसिंह गोहिल

1
@HaritsinhGohil मैंने इसका मतलब यह निकाला कि वह jQuery समाधान देने के लिए आपकी आलोचना कर रहा था। यह सच है कि jQuery से दूर जाने के लिए इन दिनों कुछ प्रोत्साहन है, और निश्चित रूप से नोड है, लेकिन जब तक कोई ओपी विशेष रूप से शुद्ध जेएस या नोड के लिए नहीं पूछता है, मुझे लगता है कि यह मानना ​​ठीक है कि कोई व्यक्ति वेब वातावरण में काम कर रहा है और वह jQuery है उपलब्ध होना लगभग तय है।
अबल्टर

4

map functionपर मौजूद नहीं है Object.prototypeलेकिन आप इसे इतना तरह का अनुकरण कर सकते हैं

var myMap = function ( obj, callback ) {

    var result = {};

    for ( var key in obj ) {
        if ( Object.prototype.hasOwnProperty.call( obj, key ) ) {
            if ( typeof callback === 'function' ) {
                result[ key ] = callback.call( obj, obj[ key ], key, obj );
            }
        }
    }

    return result;

};

var myObject = { 'a': 1, 'b': 2, 'c': 3 };

var newObject = myMap( myObject, function ( value, key ) {
    return value * value;
});

परफ्यूमेंस मुद्दे: typeof callback === 'function'बिल्कुल बेमानी। 1) mapकॉलबैक 2 के बिना कोई अर्थ नहीं है) यदि callbackफ़ंक्शन नहीं है, तो आपका mapकार्यान्वयन सिर्फ लूप के लिए अर्थहीन है। इसके अलावा, Object.prototype.hasOwnProperty.call( obj, key )थोड़ा ओवरकिल है।
अंखज़ेट

3

मैं ऐसा करने के लिए सीखने की कोशिश कर रहे एक Google खोज में पहले-आइटम के रूप में आया था, और मैंने सोचा कि मैं अन्य फ़ॉल्स्क के लिए साझा करूंगा जो हाल ही में मुझे मिला था, जो npm पैकेज का उपयोग करता है।

मुझे लगता है कि यह साझा करने के लिए दिलचस्प है क्योंकि अपरिवर्तनीय ओपी की सटीक स्थिति का अपने स्वयं के प्रलेखन में उपयोग करता है - निम्नलिखित मेरा अपना कोड नहीं है, लेकिन वर्तमान अपरिवर्तनीय-जेएस प्रलेखन से खींचा गया है:

const { Seq } = require('immutable')
const myObject = { a: 1, b: 2, c: 3 }
Seq(myObject).map(x => x * x).toObject();
// { a: 1, b: 4, c: 9 } 

ऐसा नहीं है कि Seq में अन्य गुण हैं ("Seq एक आलसी ऑपरेशन का वर्णन करता है, जिससे उन्हें मध्यवर्ती संग्रह न बनाकर सभी उच्च-क्रम संग्रह विधियों (जैसे मानचित्र और फ़िल्टर) का कुशलतापूर्वक चेन उपयोग करने की अनुमति मिलती है") और यह कि कुछ अन्य अपरिवर्तनीय डेटा संरचनाएं भी काफी कुशलता से काम कर सकती हैं।

इस पद्धति का उपयोग करने वाला कोई भी व्यक्ति npm install immutableडॉक्स पढ़ना चाहेगा:

https://facebook.github.io/immutable-js/


3

संपादित करें: नई जावास्क्रिप्ट सुविधाओं का उपयोग कर विहित तरीका है -

const identity = x =>
  x

const omap = (f = identity, o = {}) =>
  Object.fromEntries(
    Object.entries(o).map(([ k, v ]) =>
      [ k, f(v) ]
    )
  )

जहां oकुछ ऑब्जेक्ट है और fआपका मैपिंग फ़ंक्शन है। या हम कह सकते हैं, एक फ़ंक्शन दिया गया है a -> b, और प्रकार के मूल्यों के साथ एक वस्तु a, प्रकार के मूल्यों के साथ एक वस्तु का उत्पादन b। छद्म प्रकार के हस्ताक्षर के रूप में -

// omap : (a -> b, { a }) -> { b }

मूल उत्तर एक शक्तिशाली कॉम्बीनेटर को प्रदर्शित करने के लिए लिखा गया था, mapReduceजो हमें एक अलग तरीके से हमारे परिवर्तन के बारे में सोचने की अनुमति देता है

  1. m, मानचित्रण समारोह - आप से पहले भेजे तत्व को बदलने का मौका देता ...
  2. r, को कम करने के समारोह - इस समारोह मैप किया तत्व के परिणाम के साथ संचायक को जोड़ती है

सहज रूप से, mapReduceएक नया रिड्यूसर बनाता है जिसे हम सीधे प्लग कर सकते हैं Array.prototype.reduce। लेकिन इससे भी महत्वपूर्ण बात, हम ऑब्जेक्ट मोनोड omapका उपयोग करके अपने ऑब्जेक्ट फनकार कार्यान्वयन को स्पष्ट रूप से लागू कर सकते हैं , Object.assignऔर {}

const identity = x =>
  x
  
const mapReduce = (m, r) =>
  (a, x) => r (a, m (x))

const omap = (f = identity, o = {}) =>
  Object
    .keys (o)
    .reduce
      ( mapReduce
          ( k => ({ [k]: f (o[k]) })
          , Object.assign
          )
      , {}
      )
          
const square = x =>
  x * x
  
const data =
  { a : 1, b : 2, c : 3 }
  
console .log (omap (square, data))
// { a : 1, b : 4, c : 9 }

कार्यक्रम का एकमात्र हिस्सा हमें वास्तव में लिखना था नोटिस मानचित्रण कार्यान्वयन ही है -

k => ({ [k]: f (o[k]) })

जो कहता है, एक ज्ञात वस्तु oऔर कुछ कुंजी दी गई है k, एक वस्तु का निर्माण करें और जिसकी गणना की गई संपत्ति कुंजी के मूल्य पर kकॉल करने का परिणाम है ।fo[k]

mapReduceयदि हम पहले अमूर्त हैं तो हमें अनुक्रमण क्षमता की झलक मिलती हैoreduce

// oreduce : (string * a -> string * b, b, { a }) -> { b }
const oreduce = (f = identity, r = null, o = {}) =>
  Object
    .keys (o)
    .reduce
      ( mapReduce
          ( k => [ k, o[k] ]
          , f
          )
      , r
      )

// omap : (a -> b, {a}) -> {b}
const omap = (f = identity, o = {}) =>
  oreduce
    ( mapReduce
        ( ([ k, v ]) =>
            ({ [k]: f (v) })
        , Object.assign
        )
    , {}
    , o
    )

सब कुछ एक ही काम करता है, लेकिन omapअब उच्च स्तर पर परिभाषित किया जा सकता है। बेशक नया Object.entriesयह मूर्खतापूर्ण दिखता है, लेकिन अभ्यास अभी भी शिक्षार्थी के लिए महत्वपूर्ण है।

आपको mapReduceयहां पूरी क्षमता दिखाई नहीं देगी , लेकिन मैं इस जवाब को साझा करता हूं क्योंकि यह देखना दिलचस्प है कि इसे कितने स्थानों पर लागू किया जा सकता है। यदि आप रुचि रखते हैं कि यह कैसे व्युत्पन्न है और अन्य तरीके उपयोगी हो सकते हैं, तो कृपया इस उत्तर को देखें ।


4
हमें बल्कि उपयोग करें Mapऔर Map.entries, ठीक है: डी। मैं मानचित्र डेटा प्रकारों के रूप में सादे वस्तुओं के दुरुपयोग से थक गया हूं।

2
मैं सहमत हूं Mapकि जहां / जब संभव हो उपयोग किया जाना चाहिए, लेकिन यह पूरी तरह से सादे जेएस ऑब्जेक्ट्स पर इन प्रक्रियाओं का उपयोग करने की आवश्यकता को प्रतिस्थापित नहीं करता है: डी
धन्यवाद

2

@Amberlamps उत्तर के आधार पर, यहां एक उपयोगिता कार्य है (एक टिप्पणी के रूप में यह बदसूरत लग रहा था)

function mapObject(obj, mapFunc){
    return Object.keys(obj).reduce(function(newObj, value) {
        newObj[value] = mapFunc(obj[value]);
        return newObj;
    }, {});
}

और उपयोग है:

var obj = {a:1, b:3, c:5}
function double(x){return x * 2}

var newObj = mapObject(obj, double);
//=>  {a: 2, b: 6, c: 10}

2
var myObject = { 'a': 1, 'b': 2, 'c': 3 };


Object.prototype.map = function(fn){
    var oReturn = {};
    for (sCurObjectPropertyName in this) {
        oReturn[sCurObjectPropertyName] = fn(this[sCurObjectPropertyName], sCurObjectPropertyName);
    }
    return oReturn;
}
Object.defineProperty(Object.prototype,'map',{enumerable:false});





newObject = myObject.map(function (value, label) {
    return value * value;
});


// newObject is now { 'a': 1, 'b': 4, 'c': 9 }

enumerableडिफॉल्ट्सfalse
थैंक

2

मेरी प्रतिक्रिया काफी हद तक यहाँ उच्चतम श्रेणी की प्रतिक्रिया पर आधारित है और उम्मीद है कि हर कोई समझता है (मेरे GitHub पर भी यही स्पष्टीकरण है)। यही कारण है कि नक्शे के काम के साथ उनकी अशुद्धता:

Object.keys(images).map((key) => images[key] = 'url(' + '"' + images[key] + '"' +    
')');

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

कारण यह काम करता है कि। सरणी फ़ंक्शन को वापस करने के कारण यह है कि आप किसी मौजूदा ऑब्जेक्ट को केवल संशोधित करने के बजाय किसी सरणी का स्पष्ट या अंतर्निहित RETURN प्रदान कर रहे हैं। आप अनिवार्य रूप से प्रोग्राम को इस बात में उलझा देते हैं कि ऑब्जेक्ट Object.keys का उपयोग करके एक सरणी है, जो आपको व्यक्तिगत मान के साथ जुड़े मूल्यों पर अभिनय के साथ मैप फ़ंक्शन का उपयोग करने की अनुमति देगा (मैं वास्तव में गलती से वापस आए सरणियों लेकिन इसे ठीक कर दिया है)। जब तक सामान्य अर्थों में वापसी नहीं होती है, तब तक कोई ऑब्जेक्ट नहीं बनाया जाएगा जो मूल ऑब्जेक्ट स्टिल बरकरार और प्रोग्राम के रूप में संशोधित हो।

यह विशेष कार्यक्रम छवियों नामक एक वस्तु लेता है और इसकी कुंजियों के मूल्यों को लेता है और किसी अन्य फ़ंक्शन के भीतर उपयोग के लिए यूआरएल टैग जोड़ता है। मूल यह है:

var images = { 
snow: 'https://www.trbimg.com/img-5aa059f5/turbine/bs-md-weather-20180305', 
sunny: 'http://www.cubaweather.org/images/weather-photos/large/Sunny-morning-east-   
Matanzas-city- Cuba-20170131-1080.jpg', 
rain: 'https://i.pinimg.com/originals/23/d8
/ab/23d8ab1eebc72a123cebc80ce32b43d8.jpg' };

... और यह संशोधित है:

var images = { 
snow: url('https://www.trbimg.com/img-5aa059f5/turbine/bs-md-weather-20180305'),     
sunny: url('http://www.cubaweather.org/images/weather-photos/large/Sunny-morning-   
east-Matanzas-city- Cuba-20170131-1080.jpg'), 
rain: url('https://i.pinimg.com/originals/23/d8
/ab/23d8ab1eebc72a123cebc80ce32b43d8.jpg') 
};

वस्तु की मूल संरचना तब तक बरकरार रहती है जब तक कि वह सामान्य संपत्ति तक पहुँच के लिए अनुमति नहीं देती है जब तक कि वापसी नहीं होती है। क्या यह सामान्य की तरह एक सरणी वापस नहीं है और सब कुछ ठीक हो जाएगा। लक्ष्य मूल मूल्यों (छवियों [कुंजी]) की आवश्यकता है जो कुछ और नहीं करना चाहता था। जहाँ तक मुझे पता है, सरणी के उत्पादन को रोकने के लिए छवियों की कुंजी [कुंजी] होना चाहिए और किसी सरणी को वापस करने के लिए कोई निहित या स्पष्ट अनुरोध नहीं है (चर असाइनमेंट यह करता है और मेरे लिए आगे और पीछे गड़बड़ कर रहा था)।

संपादित करें:

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

const mapper = (obj, mapFn) => Object.keys(obj).reduce((result, key) => {
                result[key] = mapFn(obj)[key];
                return result;
            }, {});

var newImages = mapper(images, (value) => value);

इन कार्यों के काम करने का तरीका इस प्रकार है:

MapFn बाद में जोड़े जाने वाले फ़ंक्शन (इस मामले में (मान) => मान) लेता है और बस उस कुंजी के लिए एक मूल्य के रूप में संग्रहीत किया जाता है (या यदि आप जैसे उसने वापसी मूल्य बदल दिया है) के लिए मैप में कोई भी रिटर्न देता है ( obj) [कुंजी],

और फिर परिणाम में कुंजी के साथ जुड़े मूल मूल्य को फिर से परिभाषित करता है [key] = mapFn (obj) [कुंजी]

और परिणाम पर किए गए ऑपरेशन को वापस लौटाता है (को। फ़ंक्शन के अंत में शुरू किए गए ब्रैकेट्स में स्थित संचायक)।

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

{snow: "https://www.trbimg.com/img-5aa059f5/turbine/bs-   
md-weather-20180305", sunny: "http://www.cubaweather.org/images/weather-
photos/lmorning-east-Matanzas-city-Cuba-20170131-1080.jpg", rain: 
"https://i.pinimg.com/originals/23/d8
/ab/23d8ab1eebc72a123cebc80ce32b43d8.jpg"}

ध्यान रखें कि यह NON-NUMBERS के साथ काम करता है। आप MapFN फ़ंक्शन में किसी भी ऑब्जेक्ट को SIMPLY RETURNING THE VALUE द्वारा डुप्लिकेट कर सकते हैं।


2

पहला फ़ंक्शन प्रश्न का उत्तर देता है। यह एक नक्शा बनाता है।

दूसरा फ़ंक्शन मैप नहीं बनाता है। इसके बजाय, यह मौजूदा ऑब्जेक्ट का उपयोग करके गुणों के माध्यम से लूप करता है hasOwnProperty()। यह मानचित्र विकल्प कुछ स्थितियों में बेहतर समाधान हो सकता है।

var myObject = { 'a': 1, 'b': 2, 'c': 3 }


//creates a map (answers question, but function below is 
//much better in some situations)
var newObject = {};
makeMap();    
function makeMap() {
    for (var k in myObject) {
        var value = myObject[k];
        newObject[k] = value * value;
    }
    console.log(newObject); //mapped array
}


//Doesn't create a map, just applies the function to
//a specific property using existing data
function getValue(key) {
  for (var k in myObject) {
    if (myObject.hasOwnProperty(key)) {
      var value = myObject[key]
      return value * value; //stops iteration
    }
  }
}
Input: <input id="input" value="" placeholder="a, b or c"><br>
Output:<input id="output"><br>
<button onclick="output.value=getValue(input.value)" >Get value</button>


2
यह मूल प्रश्न का उत्तर नहीं देता है - यह किसी दिए गए फ़ंक्शन के साथ एक नई वस्तु के लिए मानों को मैप नहीं कर रहा है (यानी यह Array.prototyp.map की तरह कुछ भी नहीं है)।
मैट ब्राउन ने

@MattBrowne मैंने एक दूसरा तरीका जोड़ा है जो यकीनन एक नक्शा बनाता है। यह धीमा है, लेकिन क्या ओपी अनुरोध करता है। पहली विधि कई स्थितियों में आदर्श है, यही वजह है कि मैंने एक लूप और संपत्ति कार्यों का उपयोग किया।
विक्टर स्टोडार्ड

1

यदि आप mapपिंग में रुचि रखते हैं, तो न केवल मान बल्कि चाबियाँ भी हैं, मैंने लिखा है Object.map(valueMapper, keyMapper), जो इस तरह से व्यवहार करता है:

var source = { a: 1, b: 2 };
function sum(x) { return x + x }

source.map(sum);            // returns { a: 2, b: 4 }
source.map(undefined, sum); // returns { aa: 1, bb: 2 }
source.map(sum, sum);       // returns { aa: 2, bb: 4 }

3
मुझे लगता है क्योंकि आपने मूल रूप से केवल एक उत्तर के रूप में एक लिंक प्रदान किया है, जो कि पर आधारित है।
क्रिस राइट

अगर कभी किसी के लिए उपयोगी है npm install @mattisg/object.map:।
मैटसीजी

1

मुझे एक ऐसे संस्करण की आवश्यकता थी जो कुंजी को संशोधित करने की अनुमति देता था (@Amberlamps और @yonatanmn उत्तरों के आधार पर);

var facts = [ // can be an object or array - see jsfiddle below
    {uuid:"asdfasdf",color:"red"},
    {uuid:"sdfgsdfg",color:"green"},
    {uuid:"dfghdfgh",color:"blue"}
];

var factObject = mapObject({}, facts, function(key, item) {
    return [item.uuid, {test:item.color, oldKey:key}];
});

function mapObject(empty, obj, mapFunc){
    return Object.keys(obj).reduce(function(newObj, key) {
        var kvPair = mapFunc(key, obj[key]);
        newObj[kvPair[0]] = kvPair[1];
        return newObj;
    }, empty);
}

factObject =

{
"asdfasdf": {"color":"red","oldKey":"0"},
"sdfgsdfg": {"color":"green","oldKey":"1"},
"dfghdfgh": {"color":"blue","oldKey":"2"}
}

संपादित करें: शुरुआती वस्तु {} में पास होने के लिए थोड़ा बदलाव। इसकी अनुमति देता है [] (यदि कुंजी पूर्णांक हैं)


1

मैं विशेष रूप से उसी फ़ंक्शन का उपयोग करना चाहता था जिसे मैं किसी एकल ऑब्जेक्ट के लिए सरणियों के लिए उपयोग कर रहा था, और इसे सरल रखना चाहता था। यह मेरे लिए काम किया:

var mapped = [item].map(myMapFunction).pop();

यह इससे अलग नहीं हैvar mapped = myMapFunction(item)
थैंक

यह मेरे द्वारा देखे गए अन्य सभी "रॉकेट स्केन्सी" समाधानों की तुलना में बहुत सरल है। साझा करने के लिए धन्यवाद :)
यूरी Teixeira

1

अधिक क्या करने के लिए बारीकी से प्रतिक्रिया करने के लिए ठीक ओपी के लिए कहा, ओपी एक वस्तु चाहता है:

myObject = { 'a': 1, 'b': 2, 'c': 3 }

एक नक्शा विधि है myObject.map,

Array.prototyp.map के समान जो निम्नानुसार उपयोग किया जाएगा:

newObject = myObject.map (फ़ंक्शन (मान, लेबल) {
    वापसी मूल्य * मूल्य;
});
// newObject अब {'a': 1, 'b': 4, 'c': 9} है

Imho सबसे अच्छा ( "के रूप में मापा क्या कहा जाता है के पास " + "कोई ES {5,6,7} बेकार में आवश्यक") जवाब होगा:

myObject.map = function mapForObject(callback)
{
  var result = {};
  for(var property in this){
    if(this.hasOwnProperty(property) && property != "map"){
      result[property] = callback(this[property],property,this);
    }
  }
  return result;
}

उपरोक्त कोड जानबूझकर किसी भी भाषा की विशेषताओं का उपयोग करने से बचता है, केवल हाल के ECMAScript संस्करणों में उपलब्ध है। समस्या के ऊपर दिए गए कोड से इसे हल किया जा सकता है:

myObject = { 'a': 1, 'b': 2, 'c': 3 };

myObject.map = function mapForObject(callback)
{
  var result = {};
  for(var property in this){
    if(this.hasOwnProperty(property) && property != "map"){
      result[property] = callback(this[property],property,this);
    }
  }
  return result;
}

newObject = myObject.map(function (value, label) {
  return value * value;
});
console.log("newObject is now",newObject);
वैकल्पिक परीक्षा कोड यहाँ

इसके अलावा कुछ के द्वारा इस पर प्रोटोटाइप श्रृंखला में समाधान डालने की संभावना होगी।

Object.prototype.map = function(callback)
{
  var result = {};
  for(var property in this){
    if(this.hasOwnProperty(property)){
      result[property] = callback(this[property],property,this);
    }
  }
  return result;
}

कुछ, जो जब सावधानीपूर्वक किए जाते हैं, तो उनका कोई बुरा प्रभाव नहीं होना चाहिए और न mapही अन्य वस्तुओं की प्रभाव विधि (यानी एरे map)।


1

सबसे पहले, Object.entries (संग्रह) का उपयोग करके अपने HTMLCollection को परिवर्तित करें। तो फिर यह एक iterable है अब आप इस पर .map विधि का उपयोग कर सकते हैं।

Object.entries(collection).map(...)

संदर्भ https://medium.com/@js_tut/calling-javascript-code-on-multiple-div-elements-without-the-id-attribute-97ff6a50f31


1

फ़ंक्शन मैप परिभाषित करें

mapEntries एक कॉलबैक फ़ंक्शन लेता है जिसे ऑब्जेक्ट में प्रत्येक प्रविष्टि पर पैरामीटर मान, कुंजी और ऑब्जेक्ट के साथ बुलाया जाता है। इसे एक नया मान लौटाना चाहिए।

mapEntries को कॉलबैक से लौटाए गए नए मानों के साथ एक नई वस्तु वापस करनी चाहिए।

Object.defineProperty(Object.prototype, 'mapEntries', {
  enumerable: false,
  value: function (mapEntriesCallback) {
    return Object.fromEntries(
      Object.entries(this).map(
        ([key, value]) => [key, mapEntriesCallback(value, key, this)]
      )
    )
  }
})


// Usage example:

var object = {a: 1, b: 2, c: 3}
var newObject = object.mapEntries(value => value * value)
console.log(newObject)
//> {a: 1, b: 4, c: 9}

संपादित करें: पिछले संस्करण में यह निर्दिष्ट नहीं किया गया था कि यह एक उल्लेखनीय संपत्ति नहीं है


0

अरे थोड़ा मैपर फ़ंक्शन लिखा है जो मदद कर सकता है।

    function propertyMapper(object, src){
         for (var property in object) {   
           for (var sourceProp in src) {
               if(property === sourceProp){
                 if(Object.prototype.toString.call( property ) === '[object Array]'){
                   propertyMapper(object[property], src[sourceProp]);
                   }else{
                   object[property] = src[sourceProp];
                }
              }
            }
         }
      }

1
मुझे लगता है कि आपको "हे" के बजाय "आई" का मतलब था
कार्लो

0

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

const obj = { 'a': 1, 'b': 2, x: {'c': 3 }}
const json = JSON.stringify(obj, (k, v) => typeof v === 'number' ? v * v : v)

console.log(json)
console.log('back to json:', JSON.parse(json))


0

मैं छूट को कम करने के लिए केवल तार संभालता हूं:

Object.keys(params).map(k => typeof params[k] == "string" ? params[k] = params[k].trim() : null);

0

टाइपस्क्रिप्ट में ऑब्जेक्ट मैपर

मुझे ऐसे उदाहरण पसंद हैं जो इसObject.fromEntries तरह का उपयोग करते हैं , लेकिन फिर भी, वे उपयोग करने में बहुत आसान नहीं हैं। जवाब जो उपयोग करते हैं और फिर देखते हैं वे वास्तव में कई लुक-अप कर रहे हैं जो आवश्यक नहीं हो सकते हैं।Object.keyskey

मैं चाहती थी कि एक था Object.mapसमारोह है, लेकिन हम खुद हमारे बना सकते हैं और यह कॉल कर सकते हैं objectMapदोनों संशोधित करने की क्षमता के साथ keyऔर value:

उपयोग (जावास्क्रिप्ट):

const myObject = { 'a': 1, 'b': 2, 'c': 3 };

// keep the key and modify the value
let obj = objectMap(myObject, val => val * 2);
// obj = { a: 2, b: 4, c: 6 }


// modify both key and value
obj = objectMap(myObject,
    val => val * 2 + '',
    key => (key + key).toUpperCase());
// obj = { AA: '2', BB: '4', CC: '6' }

कोड (टाइपस्क्रिप्ट):

interface Dictionary<T> {
    [key: string]: T;
}

function objectMap<TValue, TResult>(
    obj: Dictionary<TValue>,
    valSelector: (val: TValue, obj: Dictionary<TValue>) => TResult,
    keySelector?: (key: string, obj: Dictionary<TValue>) => string,
    ctx?: Dictionary<TValue>
) {
    const ret = {} as Dictionary<TResult>;
    for (const key of Object.keys(obj)) {
        const retKey = keySelector
            ? keySelector.call(ctx || null, key, obj)
            : key;
        const retVal = valSelector.call(ctx || null, obj[key], obj);
        ret[retKey] = retVal;
    }
    return ret;
}

यदि आप टाइपस्क्रिप्ट का उपयोग नहीं कर रहे हैं, तो जावास्क्रिप्ट कोड प्राप्त करने के लिए टाइप कोड को टाइपस्क्रिप्ट प्लेग्राउंड में कॉपी करें ।

इसके अलावा, कारण मैं डाल keySelectorके बाद valSelectorपैरामीटर सूची में है, क्योंकि यह वैकल्पिक है।

* कुछ क्रेडिट अलेक्जेंडर-मिल्स के जवाब पर जाते हैं


0
const mapObject = (targetObject, callbackFn) => {
    if (!targetObject) return targetObject;
    if (Array.isArray(targetObject)){
        return targetObject.map((v)=>mapObject(v, callbackFn))
    }
    return Object.entries(targetObject).reduce((acc,[key, value]) => {
        const res = callbackFn(key, value);
        if (!Array.isArray(res) && typeof res ==='object'){
            return {...acc, [key]: mapObject(res, callbackFn)}
        }
        if (Array.isArray(res)){
            return {...acc, [key]: res.map((v)=>mapObject(v, callbackFn))}
        }
        return {...acc, [key]: res};
    },{})
};
const mapped = mapObject(a,(key,value)=> {
    if (!Array.isArray(value) && key === 'a') return ;
    if (!Array.isArray(value) && key === 'e') return [];
    if (!Array.isArray(value) && key === 'g') return value * value;
    return value;
});
console.log(JSON.stringify(mapped)); 
// {"b":2,"c":[{"d":2,"e":[],"f":[{"g":4}]}]}

यह फ़ंक्शन ऑब्जेक्ट के ऑब्जेक्ट और सरणियों के माध्यम से पुनरावर्ती जाता है। यदि अपरिभाषित लौटाया जाता है, तो विशेषताओं को हटाया जा सकता है

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.