我有一个目标:

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使用这个,所以我不关心跨浏览器问题。)


当前回答

我特别希望使用与用于单个对象的数组相同的函数,并希望保持简单。这对我有用:

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

其他回答

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

没有到Object对象的本机映射,但这如何:

var myObject={“a”:1,“b”:2,“c”:3};Object.keys(myObject).forEach(函数(键,索引){myObject[key]*=2;});console.log(myObject);//=>{“a”:2,“b”:4,“c”:6}

但是您可以使用for。。。在:

var myObject={“a”:1,“b”:2,“c”:3};for(myObject中的var键){if(myObject.hasOwnProperty(键)){myObject[key]*=2;}}console.log(myObject);//{“a”:2,“b”:4,“c”:6}

使现代化

很多人都提到,以前的方法不会返回新对象,而是对对象本身进行操作。为此,我想添加另一个解决方案,该方案返回一个新对象并保持原始对象的原样:

var myObject={“a”:1,“b”:2,“c”:3};//返回一个新对象,其中每个键的值都使用mapFn(value)映射函数objectMap(对象,mapFn){return Object.keys(Object).reduce(function(result,key){result[key]=mapFn(对象[key])返回结果}, {})}var newObject=对象映射(myObject,函数(值){返回值*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。

常量对象映射=(obj,fn)=>对象.fromEntries(对象条目(obj).map(([k,v],i)=>[k,fn(v,k,i)]))常量myObject={a:1,b:2,c:3}console.log(objectMap(myObject,v=>2*v))

我需要一个函数,不仅可以选择性地映射(也可以选择性地)值,还可以映射键。原始对象不应更改。该对象也仅包含基本值。

function mappedObject(obj, keyMapper, valueMapper) {

    const mapped = {};
    const keys   = Object.keys(obj);
    const mapKey = typeof keyMapper == 'function';
    const mapVal = typeof valueMapper == 'function';

    for (let i = 0; i < keys.length; i++) {
        const key = mapKey ? keyMapper(keys[i]) : keys[i];
        const val = mapVal ? valueMapper(obj[keys[i]]) : obj[keys[i]];
        mapped[key] = val;
    }

    return mapped;
}

使用传递keymapper和valuemapper函数:

const o1 = { x: 1, c: 2 }
mappedObject(o1, k => k + '0', v => v + 1) // {x0: 2, c0: 3}

JavaScript刚刚获得了新的Object.fromEntries方法。

实例

函数mapObject(obj,fn){返回Object.fromEntries(对象.entries(对象).map(fn))}常量myObject={a:1,b:2,c:3}const myNewObject=mapObject(myObject,([key,value])=>([key、value*value]))console.log(myNewObject)

解释

上面的代码将Object转换为可以映射的嵌套数组([[<key>,<value>],…])。Object.fromEntries将数组转换回对象。

这种模式最酷的一点是,现在可以在映射时轻松地考虑对象关键点。

文档

对象.fromEntries()Object.entries()

浏览器支持

Object.fromEntries目前仅受这些浏览器/引擎支持,但仍有polyfill可用(例如@babel/polyfill)。

您可以在返回的键数组上使用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。。在循环中使用hasOwnProperty检查。