map function for objects (instead of arrays)

前端 未结 30 1962
无人及你
无人及你 2020-11-22 04:23

I have an object:

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

I am looking for a native method, similar to Array.prototype.map

30条回答
  •  再見小時候
    2020-11-22 04:48

    The accepted answer has two drawbacks:

    • It misuses Array.prototype.reduce, because reducing means to change the structure of a composite type, which doesn't happen in this case.
    • It is not particularly reusable

    An ES6/ES2015 functional approach

    Please note that all functions are defined in curried form.

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

    • In line A o is reassigned. Since Javascript passes reference values by sharing, a shallow copy of o is generated. We are now able to mutate o within omap without mutating o in the parent scope.
    • In line B map's return value is ignored, because map performs a mutation of o. Since this side effect remains within omap and isn't visible in the parent scope, it is totally acceptable.

    This is not the fastest solution, but a declarative and reusable one. Here is the same implementation as a one-line, succinct but less readable:

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

    Addendum - why are objects not iterable by default?

    ES2015 specified the iterator and iterable protocols. But objects are still not iterable and thus not mappable. The reason is the mixing of data and program level.

提交回复
热议问题