对象的映射功能(而不是数组)

我有一个对象:

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是否map对对象具有这样的功能?(我想为Node.JS使用它,所以我不在乎跨浏览器的问题。)

Eva千羽2020/03/13 17:57:44

I handle only strings to reduce exemptions:

Object.keys(params).map(k => typeof params[k] == "string" ? params[k] = params[k].trim() : null);
JinJinGil2020/03/13 17:57:44

I specifically wanted to use the same function that I was using for arrays for a single object, and wanted to keep it simple. This worked for me:

var mapped = [item].map(myMapFunction).pop();
小哥逆天2020/03/13 17:57:44

基于@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}
伽罗乐2020/03/13 17:57:44

编辑:使用更新的JavaScript功能的规范方法是-

const identity = x =>
  x

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

o对象在哪里f是您的映射功能。或者我们可以说,给定from的函数a -> b,并且对象的类型值为type a,则产生对象的类型值为type b作为伪类型签名-

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

最初的答案是为了演示强大的组合器而编写的,mapReduce它使我们能够以不同的方式思考我们的转型

  1. m映射功能–使您有机会在...之前转换传入的元素
  2. r归约函数–该函数将累加器与映射元素的结果结合在一起

直观地,mapReduce创建一个我们可以直接插入的新的异径管Array.prototype.reduce但更重要的是,我们可以omap利用对象monoid 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是调用f键的值的结果o[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这里的全部潜力,但是我同意这个答案,因为看到可以应用多少个位置很有趣。如果您对它的派生方式以及其他有用的方法感兴趣,请参见此答案

逆天TomHarry2020/03/13 17:57:44

First, convert your HTMLCollection using Object.entries(collection). Then it’s an iterable you can now use the .map method on it.

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

reference https://medium.com/@js_tut/calling-javascript-code-on-multiple-div-elements-without-the-id-attribute-97ff6a50f31

TomJim前端2020/03/13 17:57:44

I needed a version that allowed modifying the keys as well (based on @Amberlamps and @yonatanmn answers);

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

Edit: slight change to pass in the starting object {}. Allows it to be [] (if the keys are integers)

樱阳光Pro2020/03/13 17:57:44

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)

说明

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

这种模式的妙处在于,您现在可以轻松地在映射时考虑对象键。

文献资料

浏览器支持

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

飞云斯丁GO2020/03/13 17:57:44

最低版本(es6):

Object.entries(obj).reduce((a, [k, v]) => (a[k] = v * v, a), {})
村村小小凯2020/03/13 17:57:44

这是直接的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;
};

总是必须自己实施这真是太烦了;)

如果您想要一些更复杂的东西,并且不会干扰Object类,请尝试以下操作:

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
西门GO2020/03/13 17:57:43

我来到这里的目的是寻找并将对象映射到数组的答案,并得到此页面。万一您来这里寻找与我相同的答案,这里是如何映射和对象到数组的方法。

您可以使用map从对象返回新数组,如下所示:

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