如何使用JavaScript(lodash)深度映射对象键?

Tej*_*har 16 javascript key object underscore.js lodash

https://lodash.com/docs#mapKeys

是否可以使用Lodash深度映射对象的键?如果没有,是否有另一个库提供此功能(如果与其他深度迭代和操作功能组合,甚至更好!)?另外,如何实现这一目标呢?我看到的主要斗争是识别安全,深度可迭代的纯键/值对象.抛出数组很容易,但重要的是要注意函数不应该尝试深度迭代其他对象,例如正则表达式.

预期结果 -

var obj = { a: 2, b: { c: 2, d: { a: 3 } } };
_.deepMapKeys(obj, function (val, key) {
  return key + '_hi';
});
// => { a_hi: 2, b_hi: { c_hi: 2, d_hi: { a_hi: 3 } } }
Run Code Online (Sandbox Code Playgroud)

geo*_*org 32

以下是您可以这样做的方式lodash:

_.mixin({
    'deepMapKeys': function (obj, fn) {

        var x = {};

        _.forOwn(obj, function(v, k) {
            if(_.isPlainObject(v))
                v = _.deepMapKeys(v, fn);
            x[fn(v, k)] = v;
        });

        return x;
    }
});
Run Code Online (Sandbox Code Playgroud)

这是一个更抽象的mixin,递归地应用任何给定的映射器:

_.mixin({
    deep: function (obj, mapper) {
        return mapper(_.mapValues(obj, function (v) {
            return _.isPlainObject(v) ? _.deep(v, mapper) : v;
        }));
    },
});
Run Code Online (Sandbox Code Playgroud)

用法(返回与上面相同):

obj = _.deep(obj, function(x) {
    return _.mapKeys(x, function (val, key) {
        return key + '_hi';
    });
});
Run Code Online (Sandbox Code Playgroud)

另一种选择,具有更优雅的语法:

_.mixin({
    deeply: function (map) {
        return function(obj, fn) {
            return map(_.mapValues(obj, function (v) {
                return _.isPlainObject(v) ? _.deeply(map)(v, fn) : v;
            }), fn);
        }
    },
});


obj = _.deeply(_.mapKeys)(obj, function (val, key) {
    return key + '_hi';
});
Run Code Online (Sandbox Code Playgroud)

  • 太好了!我还需要一个深入挖掘数组的`deep()`.这是:https://gist.github.com/zambon/8b2d207bd21cf4fcd47b96cd6d7f99c2 (2认同)

Kou*_*jee 8

就性能效率而言,这不是最好的,但如果您想跳过递归部分并希望保持代码干净简单,那么您可以将其字符串化为 json 并与JSON.parse附加参数(回调)一起使用,然后您可以将带有 lodash 的密钥。

JSON.parse(JSON.stringify(obj), (k, v) => _.isObject(v) ? _.mapKeys(v, (_v, _k) => _k + '_hi') : v)
Run Code Online (Sandbox Code Playgroud)

这是一个工作示例:

JSON.parse(JSON.stringify(obj), (k, v) => _.isObject(v) ? _.mapKeys(v, (_v, _k) => _k + '_hi') : v)
Run Code Online (Sandbox Code Playgroud)
let obj = { a: 2, b: { c: 2, d: { a: 3 } } };
let mappedObj = JSON.parse(JSON.stringify(obj), (k, v) => _.isObject(v) ? _.mapKeys(v, (_v, _k) => _k + '_hi') : v)
console.log(mappedObj)
Run Code Online (Sandbox Code Playgroud)


小智 5

关于georg的回答,这是我正在使用的东西。这种扩展的混合功能还增加了在对象内映射对象数组的功能,这是一个简单但重要的更改。

_.mixin({
    deeply: function (map) {
      return function (obj, fn) {
        return map(_.mapValues(obj, function (v) {
          return _.isPlainObject(v) ? _.deeply(map)(v, fn) : _.isArray(v) ? v.map(function(x) {
            return _.deeply(map)(x, fn);
          }) : v;
        }), fn);
      }
    },
  });
Run Code Online (Sandbox Code Playgroud)