වස්තු සඳහා සිතියම් ක්‍රියාකාරිත්වය (අරා වෙනුවට)


1112

මට වස්තුවක් ඇත:

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වෙනුවට භාවිතා කිරීමට මම යෝජනා කරමි .
ඔරියෝල්

18
ජේඑස් මෙම ඇදහිය නොහැකි තරම් මූලික කාර්යය සඳහා ලබා නොදීම මට පුදුමයකි.
jchook

3
Ori ඔරියෝල් ඔබට ඒ ගැන විශ්වාසද? එම්ඩීඑන් වෙබ් ලියකියවිලි වලට අනුව, අරාව මූලද්‍රව්‍ය අනුපිළිවෙල අතර Object.keysසහ Object.getOwnPropertyNames. ශුද්ධාසනයේ developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/...
බාට්

Art බාර්ට් අනුපිළිවෙල Object.keysක්‍රියාත්මක කිරීම මත රඳා පවතී. Stackoverflow.com/a/30919039/1529630
ඔරියෝල්

4
Ri ඔරියෝල් ඔබ කෙසේ හෝ වස්තූන්ගේ යතුරු අනුපිළිවෙල මත විශ්වාසය තැබිය යුතු නැත, එබැවින් එය ප්‍රශ්නයට තරමක් අදාල නොවේ - ඇණවුම තමාට වැදගත් බව ඔහු කිසි විටෙකත් නිශ්චිතව දක්වා නැති හෙයින්. ඇණවුම ඔහුට වැදගත් නම්, ඔහු කෙසේ හෝ වස්තුවක් භාවිතා නොකළ යුතුය.
බීටී

Answers:


1633

කිසිදු දේශීය ඇත 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අගය මෙන් දෙගුණයක් සමඟ එකතු වේ.

යාවත්කාලීන කරන්න

නව ES6 විශේෂාංග සමඟ, ප්‍රකාශ කිරීමට වඩාත් අලංකාර ක්‍රමයක් තිබේ 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
ඔව්, එවැනි ගැටලුවක් සඳහා මගේ විසඳුම නිර්දේශ නොකරමි. විකල්ප, වඩා හොඳ විසඳුමක් සමඟ මගේ පිළිතුර යාවත්කාලීන කළේ එබැවිනි.
ඇම්බර්ලම්ප්ස්

14
Al ඛලීල් රාවන්න මම හිතන්නේ ඔබ මෙහි කේතය වැරදියට කියවා ඇති බවයි - මෙම පිළිතුර mapනිවැරදිව භාවිතා නොකෙරේ, මන්ද එය සිදු නොකෙරේ return- එය ඇමතුමක් mapමෙන් අපයෝජනයකි forEach. ඔහු සැබවින්ම එසේ කළේ return myObject[value] * 2 නම් ප්‍රති result ලය වනුයේ මුල් අගයන් දෙගුණයක් වන අරාවකි , මුල් යතුරු දෙගුණ කළ අගයන් සහිත වස්තුවක් වෙනුවට , දෙවැන්න පැහැදිලිවම OP ඉල්ලා සිටි දෙයයි.
ඇල්නිටැක්

3
ඔබගේ @Amberlamps .reduceඋදාහරණයක් හරි, නමුත් IMHO එය තවමත් පහසුව දිගු මාර්ගය වැටී .mapඔබේ සිට, වස්තූන්, සඳහා .reducecallback බව මාර්ගය ගැලපෙන වී ඇතිවා පමණක් නොව, .reduceවැඩ, පමණක් නොව, අවශ්ය myObjectlexical පරාසය තුළ ලබා ගත හැකි. දෙවැන්න විශේෂයෙන් ඇමතුම් ලබා ගැනීමේදී ශ්‍රිත යොමු කිරීමක් කළ නොහැකි අතර ඒ වෙනුවට ස්ථානීය නිර්නාමික ශ්‍රිතයක් අවශ්‍ය වේ.
ඇල්නිටැක්

9
TBH මෙම පිළිතුරෙහි ඉදිරිපත් කර ඇති දෙවන විසඳුම (හෝ මුලින්) පමණක් ලබා දුන් පිළිතුරක් මා විසින් ඉදිරිපත් කරනු ඇත. පළමුවැන්න ක්‍රියාත්මක වන අතර එය අනිවාර්යයෙන්ම වැරදියි, නමුත් අනෙක් අය ප්‍රකාශ කර ඇති පරිදි, සිතියම ඒ ආකාරයෙන් භාවිතා කරනු දැකීමට මා කැමති නැත. මම සිතියම දුටු විට, මගේ මනස ස්වයංක්‍රීයව "වෙනස් කළ නොහැකි දත්ත ව්‍යුහයක්" ගැන
සිතයි

2
.mapඑහි ප්‍රති ing ලයක් ලෙස සිතියම් ගත කළ අරාව භාවිතා කිරීමට නොයන විට භාවිතා කිරීම සුදුසු ක්‍රමයක් නොවේ - ඔබට ඔබේ පළමු කේතය වැනි අතුරු ආබාධ පමණක් අවශ්‍ය නම්, forEachඒ වෙනුවට ඔබ අනිවාර්යයෙන්ම භාවිතා කළ යුතුය .
නිශ්චිත කාර්යසාධනය

323

සරල 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ශරීරයේ භාවිතා කරයි.
kzahel

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}))).
blackcatweb

120

ස්වදේශීය ක්‍රම නොමැත, නමුත් ලොඩාෂ් # සිතියම් අගයන් එම කාර්යය දීප්තිමත් ලෙස කරනු ඇත

_.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})අරාව ලබා ගැනීමට ඇමතිය හැකිය.

11
අරාව ලබා ගැනීම ප්‍රයෝජනවත් වන්නේ ඇයි? අවශ්‍යතාවය වූයේ සිතියම්ගත කළ වස්තුවක් සඳහා ය. මෙම වර්ගයේ දේ සඳහා අත්‍යවශ්‍යයෙන්ම ගොඩනගා ඇති ජනප්‍රිය පුස්තකාලයක් වන ලොඩාෂ් භාවිතා කිරීම සඳහා කිසිදු HTTP ඇමතුමක් නොමැත, නමුත් ES6 විසින් උපයෝගිතා ශ්‍රිත පුස්තකාල භාවිතා කිරීමේ අවශ්‍යතාවය යම් තාක් දුරට වළක්වා ඇත.
corse32

3
ලොඩාෂ් අදින්න අමතර HTTP ඇමතුමක්, මම හිතන්නේ. මෙය ඔබගේ එකම භාවිත අවස්ථාව නම්, ඇත්ත වශයෙන්ම එය අතිරික්තයකි. එසේ වුවද, ලෝඩාෂ් එතරම් පුළුල් පුස්තකාලයක් බැවින් මෙම පිළිතුර ලබා ගැනීම අර්ථවත් කරයි.
igorsantos07

2
_.map()OP විසින් නියම කර ඇති පරිදි ඔබ දෙවන තර්කය ලෙස යතුර ලබා ගන්නා බැවින් ඔබ සැබවින්ම භාවිතා කළ යුතු බව සඳහන් නොකල යුතුය .
igorsantos07

_.mapValues()2 වන තර්කය ලෙස යතුර ද සපයයි. ද _.map(): එය පමණක් පෙලගැස්මක් නැවත ලෙස මෙහි වැඩ නැහැ, විරුද්ධ නොවන_.map({ 'a': 1, 'b': 2, 'c': 3}, n => n * 3) // [3, 6, 9]
MeltedPenguin

56

එකක් ලිවීම පහසුය:

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.

සංස්කරණය කරන්න - භාවිතය ඉවත් කිරීම සඳහා වෙනස් Object.prototypeකරන mapලදි, එය වස්තුවේ නම් කර ඇති දැනට පවතින දේපල සමඟ ගැටෙන්නේ නැති බව සහතික කිරීම සඳහා .


3
හරි. :) මෙම ප්‍රශ්නය පිළිබඳ අදහස් දැක්වීමක් මා මෙහි ගෙන ආවේය. පිළිගත් පිළිතුර පැහැදිලිවම අනිසි ලෙස භාවිතා කරන බැවින් මම මෙය +1 කරමි map, නමුත් වෙනස් කිරීම Object.prototypeගණන් කළ නොහැකි වුවද මා සමඟ වෙනස් නොවන බව මා පැවසිය යුතුය .
JLRishe

2
@ ජේ.එල්.රිෂේ ස්තූතියි. ES5 හි IMHO වෙනත් ක්‍රම සමඟ ගැටීමේ (න්‍යායාත්මක) අවදානම හැර වෙනත් කිසිදු වෙනස් කිරීමක් නොකිරීමට තවත් හේතුවක් නැතObject.prototype . FWIW, අනෙක් පිළිතුරට ඇති තරම් ඡන්ද ලැබුණේ කෙසේදැයි මට තේරුම් ගත නොහැක, එය සම්පූර්ණයෙන්ම වැරදිය.
ඇල්නිටැක්

7
@JLRishe ඔබ පරණ ගීසරයක් ... වේලාවන් සමඟ ගොස් එම මූලාකෘතිය වෙනස් කරන්න!
නික් මැනිං

12
Ick නික් මැනින් ඔබ තරුණ කස පහර දෙන්නන් සහ ඔබේ වගකීම් විරහිත හැසිරීම. මගේ තණකොළෙන් බහින්න!
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 වෙත එක් කිරීම ආරක්ෂිතයි, Object.prototype වෙත එක් නොකරන්න.

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

ඔබ මෙම ශ්‍රිතය ගෝලීය Objectවස්තුවට එකතු කරන්නේ ඇයි ? තියෙනවා const mapObject = (obj, fn) => { [...]; return ret; }.
ඇම්බර්ලම්ප්ස්

7
මන්ද එය වස්තුව පිළිබඳ ක්‍රමයක් විය යුතුය :)
ඇලෙක්සැන්ඩර් මිල්ස්

1
අපි Object.prototype සමඟ පටලවා නොගන්නා තාක් කල් අපි හොඳින් සිටිය යුතුයි
ඇලෙක්සැන්ඩර් මිල්ස්

1
සිතියම අහඹු අපැහැදිලි දෙයක් නම්, විශ්වාසයි. නමුත් .mapසාමාන්‍යයෙන් එය Functor අතුරුමුහුණතක් ලෙස වටහාගෙන ඇති අතර, "Object" සඳහා Functor පිළිබඳ තනි අර්ථ දැක්වීමක් නොමැත, මන්ද ජාවාස්ක්‍රිප්ට් හි ඇති ඕනෑම දෙයක් පාහේ ඒවායේම පැහැදිලි හා අර්ථ දක්වා ඇති දේවල් ඇතුළුව වස්තුවක් විය හැකිය .map අතුරුමුහුණත් / තර්කනය.
ඩිටිප්සන්

1
මගේ මතය අනුව ඇමතුම් ලබා ගැනීමේ පළමු තර්කය යතුරක් නොව නැවත සැකසූ අංගයක් විය යුතුය. උදාහරණයක් ලෙස එය සාමාන්‍ය සිතියම සමඟ සිදු වන පරිදි එය මට එකම වස්තුවක් ලබා දිය යුතු යැයි මම සිතමි: Object.map ({prop: 1}, el => el) නමුත් එය එකම යතුරු නාමයේ වටිනාකම සහිත යතුරු ලබා දෙයි ...
ග්ලෙබ් ඩොල්සිකොව්

18

මම මෙහි පැමිණියේ වස්තුවක් අරාවකට සිතියම් ගත කිරීම සඳහා පිළිතුරු සෙවීමට සහ ප්‍රති page ලයක් ලෙස මෙම පිටුව ලබා ගනිමිනි. මම මෙහි පැමිණි එකම පිළිතුර සොයමින් ඔබ මෙහි පැමිණියේ නම්, මෙන්න ඔබට සිතියමක් හා අරාවකට විරුද්ධ විය හැකි ආකාරය.

වස්තුවෙන් නව අරාවක් ලබා දීමට ඔබට සිතියම භාවිතා කළ හැකිය:

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

6
මෙය දුරස්ථව ක්‍රියා නොකරයි - එය නව වස්තුවක් නොව වස්තුවේ අගයන් සමූහයක් ලබා දෙයි. මට විශ්වාස කරන්න බැහැ මේකට වැඩි ඡන්ද ප්‍රමාණයක් තියෙනවා කියලා.
ඇල්නිටැක්

1
ඔබ නිවැරදියි, ඔවුන් වස්තුවක් සිතියම් ගත කිරීම හා වස්තුව සිතියම් ගත කිරීම සඳහා පිළිතුරක් සොයන බැවින් එය ප්‍රශ්නයට නිවැරදිව පිළිතුරු සපයන්නේ නැත. මම මෙහි පැමිණියේ වස්තුවක් අරාවකට සිතියම් ගත කිරීම සඳහා පිළිතුරක් සොයමින් මෙම පිටුව ලබා ගත් නිසාය, එබැවින් මම මගේ පිළිතුර අතහැර එය සංස්කරණය කර එය ප්‍රති result ලයක් ලෙස මෙහි පැමිණ ඇති පුද්ගලයින්ට විකල්ප පිළිතුරක් බව පිළිබිඹු වේ. වස්තුවක් අරා වලට සිතියම් ගත කිරීම සොයමින්.
ජෝට්‍රොන්

5
ES7 හි එය සුළුපටු වනු ඇතObject.values(myObject)
Alnitak

1
එය දැන ගැනීම සතුටක්, නමුත් සමහර අයට තවමත් උරුම කේතය භාවිතා කිරීමට සිදුවේ.
ජෝට්‍රොන්

const obj = {foo: 'bar', baz: 42}; console.log (Object.entries (obj)); // [['foo', 'bar'], ['baz', 42]]
Bashirpour

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));

  • A පේළියේ oනැවත පවරා ඇත. බෙදාගැනීමෙන් ජාවාස්ක්‍රිප්ට් යොමු අගයන් පසු කරන බැවින් , නොගැඹුරු පිටපතක් oජනනය වේ. මව් විෂය පථය oතුළ විකෘති omapනොවී අපට දැන් විකෘති වීමට oහැකිය.
  • පේළියේ B mapහි ප්‍රතිලාභ අගය නොසලකා හරිනු ලැබේ, මන්ද mapවිකෘතියක් සිදු කරයි o. මෙම අතුරු ආබාධය omapමව් විෂය පථය තුළ නොපවතින බැවින් එය සම්පූර්ණයෙන්ම පිළිගත හැකිය.

මෙය වේගවත්ම විසඳුම නොව ප්‍රකාශිත හා නැවත භාවිතා කළ හැකි විසඳුමකි. එක් පේළියක් ලෙස එකම ක්‍රියාවට නැංවීම මෙන්න, සාරාංශගත නමුත් අඩු කියවිය හැකි:

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

අතිරේක - වස්තූන් පෙරනිමියෙන් නැවත ලබා ගත නොහැක්කේ ඇයි?

ES2015 මඟින් iterator සහ iterable ප්‍රොටෝකෝල නියම කර ඇත. නමුත් වස්තූන් තවමත් ක්‍රියාකාරී නොවන අතර එමඟින් සිතියම් ගත කළ නොහැක. හේතුව දත්ත හා වැඩසටහන් මට්ටම මිශ්‍ර වීමයි .


1
ඉන්ජිනේරුකරණයට වඩා ටිකක් වැඩියි; අත්‍යවශ්‍යයෙන්ම ලූපයක් සඳහා මම කාර්යයන් 6 ක් ගණන් කරමි. වෙනත් විසඳුම් බෙහෙවින් සරල වන අතර පිළිගත් පිළිතුර ද 5 ගුණයකින් වේගවත් වේ.
fregante

4
comment bfred.it ඔබේ අදහස් දැක්වීමේ අරමුණ කුමක්ද? ඔබ ක්ෂුද්‍ර ප්‍රශස්තිකරණයට කැමති නම් ඔබත් භාවිතා නොකළ Array.prototype.reduceයුතුය. මට මෙහි නිදර්ශනය කිරීමට අවශ්‍ය වන්නේ පිළිගත් පිළිතුර කෙසේ හෝ “අපයෝජනයන්” Array.prototype.reduceසහ තනිකරම ක්‍රියාකාරී සිතියම්ගත කිරීමක් ක්‍රියාත්මක කළ හැකි ආකාරයයි. ඔබ ක්‍රියාකාරී වැඩසටහන්කරණය ගැන උනන්දුවක් නොදක්වන්නේ නම්, මගේ පිළිතුර නොසලකා හරින්න.

2
"සංයුක්ත වර්ගයක ව්‍යුහය වෙනස් කිරීම සඳහා අඩු කිරීම" එය සත්‍ය යැයි මම නොසිතමි. හරියටම එකම දිගකින් හෝ එකම අගයන්ගෙන් පවා නව පෙළක් නිපදවන Array.reduce පරිපූර්ණ ලෙස නීත්‍යානුකූල වේ. අඩු කිරීම සිතියමේ සහ / හෝ පෙරනයේ ක්‍රියාකාරීත්වය නැවත නිර්මාණය කිරීම සඳහා භාවිතා කළ හැකිය (හෝ දෙකම, සංකීර්ණ සම්ප්‍රේෂකයක මෙන්, අඩු කිරීම පදනම වේ). එෆ්පී හි එය එක්තරා ආකාරයක ගුණයකින් යුක්ත වන අතර එකම වර්ගයකින් අවසන් වන ගුණයකින් තවමත් ගුණයකින් යුක්ත වේ.
ඩිටිප්සන්

2
T ඩිටිප්සන් ඔබ හරි. A (functor) foldට වඩා ජනක ය map. කෙසේ වෙතත්, මෙය 2016 මැද භාගයේ සිට මගේ දැනුම විය. එය සදාකාලික භාගයකි: D

1
හා, ඔව්. මේ සියල්ල එකිනෙකට සම්බන්ධ වී ඇති ආකාරය සහ පද සහ අතුරුමුහුණත් වල පුළුල් පරිසර පද්ධතිය අවබෝධ කර ගැනීමට මට වසර ගණනාවක් ගතවී ඇත. ඒවා එතරම් පහසු යැයි පෙනෙන දේවල් කළ නොහැකි තරම් සංකීර්ණ වන අතර, සමහර දේවල් විය නොහැකි ලෙස සංකීර්ණ වියුක්ත ලෙස පෙනේ. :)
ඩිටිප්සන්

12

JavaScript නව එකක් ලබා ගත්තා 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.fromEntriesඅරාව නැවත වස්තුවක් බවට පරිවර්තනය කරයි.

මෙම රටාවේ ඇති සිසිල්ම දෙය නම්, සිතියම්ගත කිරීමේදී ඔබට දැන් පහසුවෙන් වස්තු යතුරු සැලකිල්ලට ගත හැකිය.

ප්‍රලේඛනය

බ්‍රව්සර් සහාය

Object.fromEntriesදැනට සහය දක්වන්නේ මෙම බ්‍රව්සර් / එන්ජින් පමණි , කෙසේ වෙතත් බහු ෆිල් ඇත (උදා: බාබෙල් / පොලිෆිල් ).


2
මූලික වශයෙන්, Object.fromEntriesප්රතිවිරුද්ධයයි Object.entries. Object.entriesවස්තුවක් යතුරු අගය යුගල ලැයිස්තුවකට පරිවර්තනය කරයි. Object.fromEntriesයතුරු අගය යුගල ලැයිස්තුවක් වස්තුවකට පරිවර්තනය කරයි.
orad

9

අවම අනුවාදය (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], {})වරහන් වර්‍ග වෙනුවට කෝණික වරහන් ය.
ඇලෙක්සැන්ඩර් මිල්ස්

Lex ඇලෙක්සැන්ඩර්මිල්ස්, මගේ කේතය නිවැරදිය. වරහන් තුල කොමා ක්රියාකරු ගැන තව දුරටත් කියවන්න: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/...
Yukulélé

එය තේරුණා, ඊළඟ වතාවේ ඔබට එය පැහැදිලි කිරීමට අවශ්‍ය විය හැකිය, නමුත් මම හිතන්නේ අදහස් දැක්වෙන්නේ එයයි.
ඇලෙක්සැන්ඩර් මිල්ස්

1
මූලික වශයෙන්, මගේ කේතය සමාන වේ:Object.entries(obj).reduce((a, [k, v]) => {a[k] = v * v; return a}, {})
යුකුලාලේ

1
නියම පිළිතුර. Object.entries().reduceමම එය භාවිතා නම් ES6 + .Would හමුවීමක් වැඩි upvotes සමග සිතීමට හොඳම විසඳුම returnවෙනුවට reducer ප්රකාශයක් implicit returnහා commaIMHO කියවීමට පිළිවෙළකට නොව දුෂ්කර වන - ක්රියාකරු
Drenai

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 වෙතින් වන බැවින් එය ක්‍රියා විරහිත වන තැන IE සඳහා https://github.com/es-shims/Object.entries බහුකාර්ය කරන්න .


විනාශ කිරීම භාවිතා කරන්නේ කෙසේද ?
Константин Ван

1
_ K._ එය ඉතා මන්දගාමී විය, නමුත් මම දැන් කාර්ය සාධනය ගැන නොදනිමි. V8 v 5.6 destructuring සඳහා යම් යම් optimisations හඳුන්වා ඇති බව පෙනේ නමුත් මැනිය යුත්තේ v8project.blogspot.co.uk
Pawel

නැතහොත්, අඩු ක්‍රියාකාරී එස් 7 නමුත් වෙනස් කළ නොහැකි:const fn = v => v * 2; const newObj = Object.entries(myObject).reduce((acc, [k,v]) => Object.assign({}, acc, {[k]: fn(v)}), {});
මයික්බ්‍රිජ්

මම කල්පනා කරන්නේ වෙනත් පිළිතුරු කිසිවක් Object.entries භාවිතා නොකරන්නේ මන්ද යන්නයි. යතුරු නැවත සැකසීමට සහ ඕබ් [යතුර] භාවිතා කිරීමට වඩා එය පිරිසිදු ය.
corwin.amber

6

ඔබට mapක්‍රමවේදය සහ forEachඅරා භාවිතා කළ හැකි නමුත් ඔබට එය භාවිතා කිරීමට අවශ්‍ය නම් Objectපහත දැක්වෙන පරිදි ඇඹරීමෙන් එය භාවිතා කළ හැකිය:

Javascript (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?
මාස්ටර්සිලෝ

ඔව් ඔබට $ සහ jQuery යන දෙකම භාවිතා කළ හැකිය
හරිට්සිං ගොහිල්

1
On රොනල්ඩ් මම වරදවා වටහාගෙන ඇත, මගේ යාවත්කාලීන පිළිතුර බලන්න, අවතක්සේරු නොකිරීමට ස්තූතියි, නමුත් මගේ වැරැද්ද ගැන සැබවින්ම දැනුවත් කිරීම, ප්‍රජාව වැඩිදියුණු කිරීම ගැන ස්තූතියි.
හරිට්සිං ගොහිල්

cbcoughlan ඔව් එය හරියටම මම අදහස් දැක්වීමේදී ලියා ඇත, එය සංඛ්‍යා වර්ග කරයි, එවිට ඔබට අවශ්‍ය කුමක්ද?
හරිට්සිං ගොහිල්

1
ArHaritsinhGohil මම එය ගත්තේ ඔහු jQuery විසඳුමක් ලබා දීම ගැන ඔබව විවේචනය කරන බවයි. JQuery වෙතින් move ත් වීමට මේ දිනවල යම් පෙළඹවීමක් ඇති බව සත්‍යයකි, ඇත්ත වශයෙන්ම Node ඇත, නමුත් OP එකක් පිරිසිදු JS හෝ Node එකක් ඉල්ලන්නේ නැත්නම්, යමෙකු වෙබ් පරිසරයක වැඩ කරන බව උපකල්පනය කිරීම සුදුසු යැයි මම සිතමි. ලබා ගත හැකි බව බොහෝ දුරට විශ්වාසයි.
abalter

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 )ටිකක් වැඩිපුර.
ankhzet

3

ගූගල් සෙවුමක මෙය කිරීමට ඉගෙන ගැනීමට උත්සාහ කරන පළමු අයිතමයක් ලෙස මම මෙය ලබා ගත් අතර, මෑතකදී සොයාගත් විසඳුම සොයා ගැනීම සඳහා වෙනත් ජන කොටස් සඳහා බෙදා ගැනීමට සිතුවෙමි, එය එන්පීඑම් පැකේජය වෙනස් කළ නොහැකි ලෙස භාවිතා කරයි.

හුවමාරු කර ගැනීම සිත්ගන්නාසුළු යැයි මම සිතමි, මන්දයත් වෙනස් කළ නොහැකි OP හි නිවැරදි තත්වය ඔවුන්ගේම ලියකියවිලි වල භාවිතා කරයි - පහත දැක්වෙන්නේ මගේම කේතයක් නොව වර්තමාන වෙනස් කළ නොහැකි-ජේඑස් ප්‍රලේඛනයෙන් ඉවත් කර ඇත:

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 } 

සීක් හට වෙනත් ගුණාංග ඇති බව නොවේ ("සේක් විස්තර කරන්නේ කම්මැලි මෙහෙයුමක් වන අතර, අතරමැදි එකතු කිරීම් නිර්මාණය නොකිරීමෙන් සියලුම ඉහළ පෙළේ එකතු කිරීමේ ක්‍රම (සිතියම සහ පෙරණය වැනි) කාර්යක්ෂමව දාමයක් භාවිතා කිරීමට ඔවුන්ට ඉඩ සලසයි") සහ තවත් වෙනස් කළ නොහැකි-ජේඑස් දත්ත ව්‍යුහයන් ද එම කාර්යය කාර්යක්ෂමව කළ හැකිය.

මෙම ක්‍රමය භාවිතා කරන ඕනෑම කෙනෙකුට ඇත්ත වශයෙන්ම 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, අඩු කිරීමේ ශ්‍රිතය - මෙම ශ්‍රිතය සිතියම්ගත කළ මූලද්‍රව්‍යයේ ප්‍රති result ලය සමඟ සමුච්චය ඒකාබද්ධ කරයි

බුද්ධිමත්ව, mapReduceඅපට කෙලින්ම සම්බන්ධ කළ හැකි නව අඩු කරන්නෙකු නිර්මාණය කරයි Array.prototype.reduce. එහෙත් වඩා වැදගත්, අපි අපේ වස්තුව functor ක්රියාත්මක කිරීම ක්රියාත්මක කළ හැකි 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, වස්තුවක් තැනීම සහ යතුරේ වටිනාකම ඇමතීමේ ප්‍රති comp ලය ගණනය කළ දේපල 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, හරි: D. සිතියම් දත්ත වර්ග ලෙස සරල වස්තූන් අනිසි ලෙස භාවිතා කිරීම ගැන මට මහන්සියි.

2
Mapහැකි සෑම අවස්ථාවකදීම භාවිතා කළ යුතු බව මම එකඟ වෙමි , නමුත් සරල JS වස්තූන් මත මෙම ක්‍රියා පටිපාටි භාවිතා කිරීමේ අවශ්‍යතාවය මුළුමනින්ම ප්‍රතිස්ථාපනය නොකරයි: D
ස්තූතියි

2

@ ඇම්බර්ලම්ප්ස් පිළිතුර මත පදනම්ව, මෙන්න උපයෝගිතා ශ්‍රිතයක් (විවරණයක් ලෙස එය කැත ලෙස පෙනුණි)

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] + '"' +    
')');

ශ්‍රිතයේ පරමාර්ථය වන්නේ අරාවක් ආපසු නොගෙන සියලු වස්තූන් (වස්තු සහ අරා එක හා සමානව) ලබා ගත හැකි ක්‍රමයක් භාවිතා කරමින් වස්තුවක් ගෙන එහි මුල් අන්තර්ගතය වෙනස් කිරීමයි. JS තුළ ඇති සෑම දෙයක්ම පාහේ වස්තුවක් වන අතර, එම හේතුව නිසා උරුමයේ නල මාර්ගයට පහළින් ඇති මූලද්‍රව්‍යයන් තාක්‍ෂණිකව රේඛාවට ඉහළින් සිටින අයට භාවිතා කළ හැකිය (සහ එය පෙනෙන පරිදි).

මෙය ක්‍රියාත්මක වීමට හේතුව .map ශ්‍රිතයන් අරාව නැවත ලබා දීමයි. ඔබ දැනට පවතින වස්තුවක් වෙනස් කිරීම වෙනුවට අරාවෙහි පැහැදිලි හෝ ව්‍යංගයෙන් නැවත පැමිණීම අවශ්‍ය වේ. Object.keys භාවිතා කිරීමෙන් වස්තුව අරාව යැයි සිතීමට ඔබ මූලිකවම උපක්‍රම යොදනු ඇත, එමඟින් එක් එක් යතුරු සම්බන්ධ කර ඇති අගයන් මත එහි ක්‍රියාකාරිත්වය සමඟ සිතියම් ක්‍රියාකාරිත්වය භාවිතා කිරීමට ඔබට ඉඩ සලසයි (මම අහම්බෙන් අරා ආපසු ලබා දුන්නද එය සවි කළෙමි). සාමාන්‍ය අර්ථයෙන් ආපසු යාමක් සිදු නොවන තාක් කල්, මුල් වස්තුව නොනවත්වා නිර්මාණය කර ඇති අතර ක්‍රමලේඛනය කළ පරිදි වෙනස් කරනු නොලැබේ.

මෙම විශේෂිත වැඩසටහන රූප ලෙස හැඳින්වෙන වස්තුවක් ගෙන එහි යතුරු වල අගයන් ගෙන වෙනත් ශ්‍රිතයක් තුළ භාවිතා කිරීම සඳහා url ටැග් එකතු කරයි. මුල් පිටපත මෙයයි:

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 පසුව එකතු කළ යුතු ශ්‍රිතය (මේ අවස්ථාවේ දී (අගය) => අගය) ගෙන එම යතුර සඳහා වටිනාකමක් ලෙස එහි ගබඩා කර ඇති ඕනෑම දෙයක් ආපසු ලබා දෙයි (නැතහොත් ඔහු මෙන් ප්‍රතිලාභ අගය වෙනස් කළහොත් දෙකකින් ගුණ කළහොත්) mapFn ( obj) [යතුර],

ප්‍රති result ලයක් ලෙස යතුර හා සම්බන්ධ මුල් අගය නැවත අර්ථ දක්වයි [key] = mapFn (obj) [key]

සහ ප්‍රති result ලය මත සිදු කරන ලද මෙහෙයුම නැවත ලබා දෙයි (.reduce ශ්‍රිතය අවසානයේ ආරම්භ කරන ලද වරහන් තුළ ඇති සමුච්චය).

මේ සියල්ල තෝරාගත් වස්තුව මත සිදු කෙරෙන අතර නැවත එහි ආපසු එන අරාවක් සඳහා ව්‍යාජ ඉල්ලීමක් විය නොහැකි අතර එය ක්‍රියාත්මක වන්නේ මට කිව හැකි තාක් දුරට අගයන් නැවත පැවරීමේදී පමණි. මේ සඳහා සමහර මානසික ජිම්නාස්ටික් අවශ්‍ය වන නමුත් ඉහත දැකිය හැකි පරිදි කේත රේඛා අඩු කරයි. ප්‍රතිදානය පහත දැක්වෙන ආකාරයටම සමාන වේ:

{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 ශ්‍රිතයේ අගය සරලව නැවත ලබා දීමෙන් ඔබට ඕනෑම වස්තුවක් අනුපිටපත් කළ හැකිය.


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.prototype.map වැනි දෙයක් නොවේ).
මැට් බ්‍රවුන්

Att මැට් බ්‍රවුන් මම සිතියමක් නිර්මාණය කරන දෙවන ක්‍රමයක් එකතු කළෙමි. එය මන්දගාමී ය, නමුත් OP ඉල්ලා සිටින දේ කරයි. පළමු ක්‍රමය බොහෝ අවස්ථාවන්හීදී වඩාත් සුදුසු වේ, ඒ නිසා මම ලූපයක් සහ දේපල කාර්යයන් භාවිතා කළෙමි.
වික්ටර් ස්ටෝඩාර්ඩ්

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.
MattiSG

1

මට යතුරු වෙනස් කිරීමට ඉඩ දෙන අනුවාදයක් අවශ්‍ය විය (@ ඇම්බර්ලම්ප්ස් සහ onyonatanmn පිළිතුරු මත පදනම්ව);

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"}
}

සංස්කරණය කරන්න: ආරම්භක වස්තුව තුළ pass සුළු වෙනසක් සිදු කිරීම {}. එය වීමට ඉඩ දෙන්න [] (යතුරු පූර්ණ සංඛ්‍යා නම්)


1

තනි වස්තුවක් සඳහා අරා සඳහා මා භාවිතා කළ එකම ශ්‍රිතය භාවිතා කිරීමට මට විශේෂයෙන් අවශ්‍ය වූ අතර එය සරලව තබා ගැනීමට අවශ්‍ය විය. මෙය මට ප්‍රයෝජනවත් විය:

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

මෙය ඊට වඩා වෙනස් නොවේvar mapped = myMapFunction(item)
ස්තූතියි

මා මෙහි දුටු අනෙක් "රොකට් ස්කයිසි" විසඳුම් වලට වඩා මෙය ඉතා සරල ය. බෙදාහදා ගැනීමට ස්තූතියි :)
යූරි ටෙක්සෙයිරා

1

ප්රතිචාර සඳහා වඩා සමීපව දේ හරියටම මෙම විශ්රාම වැටුප් ඉල්ලා එම විශ්රාම වැටුප් වස්තුවක් අවශ්ය:

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

සිතියම් ක්‍රමයක් තිබීමට myObject.map,

Array.prototype.map ට සමාන වන අතර එය පහත පරිදි භාවිතා වේ:

newObject = myObject.map (ශ්‍රිතය (අගය, ලේබලය) {
    ප්‍රතිලාභ අගය * අගය;
});
// newObject දැන් {'a': 1, 'b': 4, 'c': 9 is

මෙම 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;
}

යම් දෙයක්, සුපරීක්ෂාකාරීව අධීක්ෂණය කරන විට කිසිදු අයහපත් ප්‍රති and mapල ඇති නොවිය යුතු අතර වෙනත් වස්තූන්ගේ බලපෑම් ක්‍රමයක් නොවිය යුතුය (එනම් අරාගේ map).



1

ශ්‍රිත සිතියමක් නිර්වචනය කරන්න එන්ට්‍රීස්.

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}

සංස්කරණය කරන්න: පෙර අනුවාදයක මෙය ගණන් කළ නොහැකි දේපලක් නොවන බව සඳහන් කර නැත


1

පහත සඳහන් දෑ භාවිතා කිරීමෙන් ඔබට වස්තුවක් අරාව බවට පරිවර්තනය කළ හැකිය:

ඔබට වස්තු අගයන් අරාවකට පරිවර්තනය කළ හැකිය:

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

let valuesArray = Object.values(myObject);

console.log(valuesArray);

ඔබට වස්තු යතුරු අරාවකට පරිවර්තනය කළ හැකිය:

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

let keysArray = Object.keys(myObject);

console.log(keysArray);

දැන් ඔබට 'සිතියම්' ශ්‍රිතය ඇතුළුව සාමාන්‍ය අරා මෙහෙයුම් සිදු කළ හැකිය


2020 දී මෙය පිළිගත් පිළිතුර විය යුතු යැයි මම සිතමි.
ඩවුඩ්

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 stringify ශ්‍රිතයක් භාවිතා කිරීම ඊට වෙනස් ආකාරයකි. ඔබ එය කෙසේ හෝ 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.keysසහ පසුව සොයා බලයිkey ඇත්ත වශයෙන්ම අවශ්‍ය නොවන බහු-බැලීම් සිදු කරයි.

මම එහි බලාපොරොත්තු Object.mapකාර්යය, නමුත් අපි අපේ ම නිර්මාණය කළ හැකි අතර එය අමතන්න objectMapදෙකම වෙනස් කිරීමට ඇති හැකියාව සමග keyහා value:

භාවිතය (JavaScript):

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පරාමිතිය ලැයිස්තුවේ වේ එය විකල්ප නිසා.

* සමහර ණය ඇලෙක්සැන්ඩර් මෝල්වල පිළිතුරට යයි .

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.