我有一个目标:

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 }

JavaScript是否有这样的对象映射函数?(我希望Node.JS使用这个,所以我不关心跨浏览器问题。)


当前回答

您可以在数组上使用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}

其他回答

TypeScript中的对象映射器

我喜欢像这样使用Object.fromEntries的示例,但它们仍然不太好用。使用Object.keys然后查找关键字的答案实际上是在进行可能不需要的多次查找。

我希望有一个Object.map函数,但我们可以创建自己的函数,并将其称为objectMap,同时可以修改键和值:

用法(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' }

代码(TypeScript):

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

如果您没有使用TypeScript,请在TypeScript Playground中复制上述代码以获取JavaScript代码。

此外,我在参数列表中将keySelector放在valSelector之后的原因是它是可选的。

*亚历山大·米尔斯的回答值得称赞。

如果您不仅对值感兴趣,而且对键感兴趣,我已经编写了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 }

没有原生方法,但lodash#mapValues将出色地完成这项工作

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

只需使用以下命令,即可将对象转换为数组:

可以将对象值转换为数组:

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

现在您可以执行正常的数组操作,包括“map”函数

为了更准确地响应OP的要求,OP需要一个对象:

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

要使用映射方法myObject.map,

类似于Array.prototype.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=函数mapForObject(回调){var结果={};for(此中的var属性){如果(this.hasOwnProperty(property)&&property!=“地图”){result[property]=回调(this[property],property,this);}}返回结果;}newObject=myObject.map(函数(值,标签){返回值*值;});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;
}

在仔细监督的情况下进行的操作不会产生任何不良影响,也不会影响其他对象的贴图方法(即阵列的贴图)。